示例#1
0
文件: hashtable.c 项目: SamB/zsh
static void
printshfuncnode(HashNode hn, int printflags)
{
    Shfunc f = (Shfunc) hn;
    char *t = 0;
 
    if ((printflags & PRINT_NAMEONLY) ||
	((printflags & PRINT_WHENCE_SIMPLE) &&
	!(printflags & PRINT_WHENCE_FUNCDEF))) {
	zputs(f->node.nam, stdout);
	putchar('\n');
	return;
    }
 
    if ((printflags & (PRINT_WHENCE_VERBOSE|PRINT_WHENCE_WORD)) &&
	!(printflags & PRINT_WHENCE_FUNCDEF)) {
	nicezputs(f->node.nam, stdout);
	printf((printflags & PRINT_WHENCE_WORD) ? ": function\n" :
	       " is a shell function\n");
	return;
    }
 
    quotedzputs(f->node.nam, stdout);
    if (f->funcdef || f->node.flags & PM_UNDEFINED) {
	printf(" () {\n\t");
	if (f->node.flags & PM_UNDEFINED)
	    printf("%c undefined\n\t", hashchar);
	else
	    t = getpermtext(f->funcdef, NULL, 1);
	if (f->node.flags & PM_TAGGED)
	    printf("%c traced\n\t", hashchar);
	if (!t) {
	    char *fopt = "Utkz";
	    int flgs[] = {
		PM_UNALIASED, PM_TAGGED, PM_KSHSTORED, PM_ZSHSTORED, 0
	    };
	    int fl;;

	    zputs("builtin autoload -X", stdout);
	    for (fl=0;fopt[fl];fl++)
		if (f->node.flags & flgs[fl]) putchar(fopt[fl]);
	} else {
	    zputs(t, stdout);
	    zsfree(t);
	    if (f->funcdef->flags & EF_RUN) {
		printf("\n\t");
		quotedzputs(f->node.nam, stdout);
		printf(" \"$@\"");
	    }
	}   
	printf("\n}\n");
    } else {
	printf(" () { }\n");
    }
}
示例#2
0
文件: sched.c 项目: biocyberman/zsh
static void
checksched(void)
{
    time_t t;
    struct schedcmd *sch;

    if(!schedcmds)
	return;
    t = time(NULL);
    /*
     * List is ordered, so we only need to consider the
     * head element.
     */
    while (schedcmds && schedcmds->time <= t) {
	/*
	 * Remove the entry to be executed from the list
	 * before execution:  this makes quite sure that
	 * the entry hasn't been monkeyed with when we
	 * free it.
	 */
	sch = schedcmds;
	schedcmds = sch->next;
	/*
	 * Delete from the timed function list now in case
	 * the called code reschedules.
	 */
	scheddeltimed();

	if ((sch->flags & SCHEDFLAG_TRASH_ZLE) && zleactive)
	    zleentry(ZLE_CMD_TRASH);
	execstring(sch->cmd, 0, 0, "sched");
	zsfree(sch->cmd);
	zfree(sch, sizeof(struct schedcmd));

	/*
	 * Fix time for future events.
	 * I had this outside the loop, for a little extra efficiency.
	 * However, it then occurred to me that having the list of
	 * forthcoming entries up to date could be regarded as
	 * a feature, and the inefficiency is negligible.
	 *
	 * Careful in case the code we called has already set
	 * up a timed event; if it has, that'll be up to date since
	 * we haven't changed the list here.
	 */
	if (schedcmds && !schedcmdtimed) {
	    /*
	     * We've already delete the function from the list.
	     */
	    DPUTS(timedfns && firstnode(timedfns),
		  "BUG: already timed fn (1)");
	    schedaddtimed(schedcmds->time);
	}
    }
}
示例#3
0
static void
set_buffer(UNUSED(Param pm), char *x)
{
    if(x) {
	setline(x, 0);
	zsfree(x);
    } else
	zlecs = zlell = 0;
    fixsuffix();
    menucmp = 0;
}
示例#4
0
文件: zprof.c 项目: AMDmi3/zsh
static void
freepfuncs(Pfunc f)
{
    Pfunc n;

    for (; f; f = n) {
	n = f->next;
	zsfree(f->name);
	zfree(f, sizeof(*f));
    }
}
示例#5
0
文件: complete.c 项目: Jaharmi/zsh
mod_export void
ignore_suffix(int l)
{
    if (l) {
	char *tmp, sav;
	int sl = strlen(compsuffix);

	if ((l = sl - l) < 0)
	    l = 0;

	tmp = tricat(compsuffix + l, compisuffix, "");
	zsfree(compisuffix);
	compisuffix = tmp;
	sav = compsuffix[l];
	compsuffix[l] = '\0';
	tmp = ztrdup(compsuffix);
	compsuffix[l] = sav;
	zsfree(compsuffix);
	compsuffix = tmp;
    }
}
示例#6
0
文件: zle_misc.c 项目: MPOWER4RU/zsh
mod_export void
makesuffixstr(char *f, char *s, int n)
{
    if (f) {
	zsfree(suffixfunc);
	suffixfunc = ztrdup(f);
	suffixfunclen = n;
    } else if (s) {
	int inv, i, z = 0;
	ZLE_STRING_T ws, lasts, wptr;

	if (*s == '^' || *s == '!') {
	    inv = 1;
	    s++;
	} else
	    inv = 0;
	s = getkeystring(s, &i, GETKEYS_SUFFIX, &z);
	s = metafy(s, i, META_USEHEAP);
	ws = stringaszleline(s, 0, &i, NULL, NULL);

	/* Remove suffix on uninsertable characters if  \- was given *
	 * and the character class wasn't negated -- or vice versa.  */
	suffixnoinsrem = z ^ inv;
	suffixlen = n;

	lasts = wptr = ws;
	while (i) {
	    if (i >= 3 && wptr[1] == ZWC('-')) {
		ZLE_CHAR_T str[2];

		if (wptr > lasts)
		    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
			      lasts, wptr - lasts, n);
		str[0] = *wptr;
		str[1] = wptr[2];
		addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, 0,
			  str, 2, n);

		wptr += 3;
		i -= 3;
		lasts = wptr;
	    } else {
		wptr++;
		i--;
	    }
	}
	if (wptr > lasts)
	    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
		      lasts, wptr - lasts, n);
	free(ws);
    } else
	makesuffix(n);
}
示例#7
0
文件: complete.c 项目: Jaharmi/zsh
mod_export void
ignore_prefix(int l)
{
    if (l) {
	char *tmp, sav;
	int pl = strlen(compprefix);

	if (l > pl)
	    l = pl;

	sav = compprefix[l];

	compprefix[l] = '\0';
	tmp = tricat(compiprefix, compprefix, "");
	zsfree(compiprefix);
	compiprefix = tmp;
	compprefix[l] = sav;
	tmp = ztrdup(compprefix + l);
	zsfree(compprefix);
	compprefix = tmp;
    }
}
示例#8
0
文件: hashtable.c 项目: lol768/zsh
static void
freeshfuncnode(HashNode hn)
{
    Shfunc shf = (Shfunc) hn;

    zsfree(shf->node.nam);
    if (shf->funcdef)
	freeeprog(shf->funcdef);
    if (shf->redir)
	freeeprog(shf->redir);
    zsfree(shf->filename);
    if (shf->sticky) {
	if (shf->sticky->n_on_opts)
	    zfree(shf->sticky->on_opts,
		  shf->sticky->n_on_opts * sizeof(*shf->sticky->on_opts));
	if (shf->sticky->n_off_opts)
	    zfree(shf->sticky->off_opts,
		  shf->sticky->n_off_opts * sizeof(*shf->sticky->off_opts));
	zfree(shf->sticky, sizeof(*shf->sticky));
    }
    zfree(shf, sizeof(struct shfunc));
}
示例#9
0
文件: zle_misc.c 项目: MPOWER4RU/zsh
mod_export void
addsuffixstring(int tp, int flags, char *chars, int lensuf)
{
    int slen, alloclen;
    ZLE_STRING_T suffixstr;

    /* string needs to be writable... I've been regretting this for years.. */
    chars = ztrdup(chars);
    suffixstr = stringaszleline(chars, 0, &slen, &alloclen, NULL);
    addsuffix(tp, flags, suffixstr, slen, lensuf);
    zfree(suffixstr, alloclen);
    zsfree(chars);
}
示例#10
0
文件: files.c 项目: AMDmi3/zsh
static int
domove(char *nam, MoveFunc movefn, char *p, char *q, int flags)
{
    struct stat st;
    char *pbuf, *qbuf;

    pbuf = ztrdup(unmeta(p));
    qbuf = unmeta(q);
    if(flags & MV_NODIRS) {
	errno = EISDIR;
	if(lstat(pbuf, &st) || S_ISDIR(st.st_mode)) {
	    zwarnnam(nam, "%s: %e", p, errno);
	    zsfree(pbuf);
	    return 1;
	}
    }
    if(!lstat(qbuf, &st)) {
	int doit = flags & MV_FORCE;
	if(S_ISDIR(st.st_mode)) {
	    zwarnnam(nam, "%s: cannot overwrite directory", q);
	    zsfree(pbuf);
	    return 1;
	} else if(flags & MV_INTERACTIVE) {
	    nicezputs(nam, stderr);
	    fputs(": replace `", stderr);
	    nicezputs(q, stderr);
	    fputs("'? ", stderr);
	    fflush(stderr);
	    if(!ask()) {
		zsfree(pbuf);
		return 0;
	    }
	    doit = 1;
	} else if((flags & MV_ASKNW) &&
		!S_ISLNK(st.st_mode) &&
		access(qbuf, W_OK)) {
	    nicezputs(nam, stderr);
	    fputs(": replace `", stderr);
	    nicezputs(q, stderr);
	    fprintf(stderr, "', overriding mode %04o? ",
		mode_to_octal(st.st_mode));
	    fflush(stderr);
	    if(!ask()) {
		zsfree(pbuf);
		return 0;
	    }
	    doit = 1;
	}
	if(doit && !(flags & MV_ATOMIC))
	    unlink(qbuf);
    }
    if(movefn(pbuf, qbuf)) {
	zwarnnam(nam, "%s: %e", p, errno);
	zsfree(pbuf);
	return 1;
    }
    zsfree(pbuf);
    return 0;
}
示例#11
0
文件: complete.c 项目: Jaharmi/zsh
mod_export void
freecmlist(Cmlist l)
{
    Cmlist n;

    while (l) {
	n = l->next;
	freecmatcher(l->matcher);
	zsfree(l->str);

	zfree(l, sizeof(struct cmlist));

	l = n;
    }
}
示例#12
0
文件: sched.c 项目: biocyberman/zsh
int
cleanup_(Module m)
{
    struct schedcmd *sch, *schn;

    if (schedcmds)
	scheddeltimed();
    for (sch = schedcmds; sch; sch = schn) {
	schn = sch->next;
	zsfree(sch->cmd);
	zfree(sch, sizeof(*sch));
    }
    delprepromptfn(&checksched);
    return setfeatureenables(m, &module_features, NULL);
}
示例#13
0
static void
scanfindfunc(char *seq, Thingy func, UNUSED(char *str), void *magic)
{
    struct findfunc *ff = magic;

    if(func != ff->func)
	return;
    if (!ff->found++)
	ff->msg = appstr(ff->msg, " is on");
    if(ff->found <= MAXFOUND) {
	char *b = bindztrdup(seq);

	ff->msg = appstr(ff->msg, " ");
	ff->msg = appstr(ff->msg, b);
	zsfree(b);
    }
}
示例#14
0
int
whereis(UNUSED(char **args))
{
    struct findfunc ff;

    if (!(ff.func = executenamedcommand("Where is: ")))
	return 1;
    ff.found = 0;
    ff.msg = nicedup(ff.func->nam, 0);
    scankeymap(curkeymap, 1, scanfindfunc, &ff);
    if (!ff.found)
	ff.msg = appstr(ff.msg, " is not bound to any key");
    else if(ff.found > MAXFOUND)
	ff.msg = appstr(ff.msg, " et al");
    showmsg(ff.msg);
    zsfree(ff.msg);
    return 0;
}
示例#15
0
static void
set_rbuffer(UNUSED(Param pm), char *x)
{
    ZLE_STRING_T y;
    int len;

    if (x && *x != ZWC('\0'))
	y = stringaszleline(x, 0, &len, NULL, NULL);
    else
	y = ZWS(""), len = 0;
    sizeline(zlell = zlecs + len);
    ZS_memcpy(zleline + zlecs, y, len);
    zsfree(x);
    if (len)
	free(y);
    fixsuffix();
    menucmp = 0;
}
示例#16
0
mod_export void
deletehashtable(HashTable ht)
{
    ht->emptytable(ht);
#ifdef ZSH_HASH_DEBUG
    if(ht->next)
	ht->next->last = ht->last;
    else
	lastht = ht->last;
    if(ht->last)
	ht->last->next = ht->next;
    else
	firstht = ht->next;
    zsfree(ht->tablename);
#endif /* ZSH_HASH_DEBUG */
    zfree(ht->nodes, ht->hsize * sizeof(HashNode));
    zfree(ht, sizeof(*ht));
}
示例#17
0
文件: zle_utils.c 项目: Lujaw/zsh
char *
bindztrdup(char *str)
{
    int c, len = 1;
    char *buf, *ptr, *ret;

    for(ptr = str; *ptr; ptr++) {
	c = *ptr == Meta ? STOUC(*++ptr) ^ 32 : STOUC(*ptr);
	if(c & 0x80) {
	    len += 3;
	    c &= 0x7f;
	}
	if(c < 32 || c == 0x7f) {
	    len++;
	    c ^= 64;
	}
	len += c == '\\' || c == '^';
	len++;
    }
    ptr = buf = zalloc(len);
    for(; *str; str++) {
	c = *str == Meta ? STOUC(*++str) ^ 32 : STOUC(*str);
	if(c & 0x80) {
	    *ptr++ = '\\';
	    *ptr++ = 'M';
	    *ptr++ = '-';
	    c &= 0x7f;
	}
	if(c < 32 || c == 0x7f) {
	    *ptr++ = '^';
	    c ^= 64;
	}
	if(c == '\\' || c == '^')
	    *ptr++ = '\\';
	*ptr++ = c;
    }
    *ptr = 0;
    ret = dquotedztrdup(buf);
    zsfree(buf);
    return ret;
}
示例#18
0
void
printshfuncnode(HashNode hn, int printflags)
{
    Shfunc f = (Shfunc) hn;
    char *t;
 
    if ((printflags & PRINT_NAMEONLY) ||
	((printflags & PRINT_WHENCE_SIMPLE) &&
	!(printflags & PRINT_WHENCE_FUNCDEF))) {
	zputs(f->nam, stdout);
	putchar('\n');
	return;
    }
 
    if ((printflags & PRINT_WHENCE_VERBOSE) &&
	!(printflags & PRINT_WHENCE_FUNCDEF)) {
	nicezputs(f->nam, stdout);
	printf(" is a shell function\n");
	return;
    }
 
    if (f->flags & PM_UNDEFINED)
	printf("undefined ");
    if (f->flags & PM_TAGGED)
	printf("traced ");
    if (!f->funcdef) {
	nicezputs(f->nam, stdout);
	printf(" () { }\n");
	return;
    }
 
    t = getpermtext((void *) dupstruct((void *) f->funcdef));
    quotedzputs(f->nam, stdout);
    printf(" () {\n\t");
    zputs(t, stdout);
    printf("\n}\n");
    zsfree(t);
}
示例#19
0
文件: prompt.c 项目: jackleaks/zsh
static void
promptpath(char *p, int npath, int tilde)
{
    char *modp = p;
    Nameddir nd;

    if (tilde && ((nd = finddir(p))))
	modp = tricat("~", nd->node.nam, p + strlen(nd->dir));

    if (npath) {
	char *sptr;
	if (npath > 0) {
	    for (sptr = modp + strlen(modp); sptr > modp; sptr--) {
		if (*sptr == '/' && !--npath) {
		    sptr++;
		    break;
		}
	    }
	    if (*sptr == '/' && sptr[1] && sptr != modp)
		sptr++;
	    stradd(sptr);
	} else {
	    char cbu;
	    for (sptr = modp+1; *sptr; sptr++)
		if (*sptr == '/' && !++npath)
		    break;
	    cbu = *sptr;
	    *sptr = 0;
	    stradd(modp);
	    *sptr = cbu;
	}
    } else
	stradd(modp);

    if (p != modp)
	zsfree(modp);
}
示例#20
0
文件: complete.c 项目: Jaharmi/zsh
static void
compunsetfn(Param pm, int exp)
{
    if (exp) {
	if (pm->u.data) {
	    if (PM_TYPE(pm->node.flags) == PM_SCALAR) {
		zsfree(*((char **) pm->u.data));
		*((char **) pm->u.data) = ztrdup("");
	    } else if (PM_TYPE(pm->node.flags) == PM_ARRAY) {
		freearray(*((char ***) pm->u.data));
		*((char ***) pm->u.data) = zshcalloc(sizeof(char *));
	    } else if (PM_TYPE(pm->node.flags) == PM_HASHED) {
		deleteparamtable(pm->u.hash);
		pm->u.hash = NULL;
	    }
	}
    } else if (PM_TYPE(pm->node.flags) == PM_HASHED) {
	Param *p;
	int i;

	deletehashtable(pm->u.hash);
	pm->u.hash = NULL;

	for (p = compkpms, i = CP_KEYPARAMS; i--; p++)
	    *p = NULL;
    }
    if (!exp) {
	Param *p;
	int i;

	for (p = comprpms, i = CP_REALPARAMS; i; p++, i--)
	    if (*p == pm) {
		*p = NULL;
		break;
	    }
    }
}
示例#21
0
void
freehistdata(Histent he, int unlink)
{
    if (!he)
	return;

    if (!(he->flags & (HIST_DUP | HIST_TMPSTORE)))
	removehashnode(histtab, he->text);

    zsfree(he->text);
    if (he->nwords)
	zfree(he->words, he->nwords*2*sizeof(short));

    if (unlink) {
	if (!--histlinect)
	    hist_ring = NULL;
	else {
	    if (he == hist_ring)
		hist_ring = hist_ring->up;
	    he->up->down = he->down;
	    he->down->up = he->up;
	}
    }
}
示例#22
0
文件: zle_misc.c 项目: MPOWER4RU/zsh
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();
}
示例#23
0
文件: zle_misc.c 项目: MPOWER4RU/zsh
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;
}
示例#24
0
文件: zselect.c 项目: AMDmi3/zsh
static int
bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
#ifdef HAVE_SELECT
    int i, fd, fdsetind = 0, fdmax = 0, fdcount;
    fd_set fdset[3];
    const char fdchar[3] = "rwe";
    struct timeval tv, *tvptr = NULL;
    char *outarray = "reply", **outdata, **outptr;
    char *outhash = NULL;
    LinkList fdlist;

    for (i = 0; i < 3; i++)
	FD_ZERO(fdset+i);

    for (; *args; args++) {
	char *argptr = *args, *endptr;
	zlong tempnum;
	if (*argptr == '-') {
	    for (argptr++; *argptr; argptr++) {
		switch (*argptr) {
		    /*
		     * Array name for reply, if not $reply.
		     * This gets set to e.g. `-r 0 -w 1' if 0 is ready
		     * for reading and 1 is ready for writing.
		     */
		case 'a':
		case 'A':
		    i = *argptr;
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (idigit(*argptr) || !isident(argptr)) {
			zwarnnam(nam, "invalid array name: %s", argptr);
			return 1;
		    }
		    if (i == 'a')
			outarray = argptr;
		    else
			outhash = argptr;
		    /* set argptr to next to last char because of increment */
		    while (argptr[1])
			argptr++;
		    break;

		    /* Following numbers indicate fd's for reading */
		case 'r':
		    fdsetind = 0;
		    break;

		    /* Following numbers indicate fd's for writing */
		case 'w':
		    fdsetind = 1;
		    break;

		    /* Following numbers indicate fd's for errors */
		case 'e':
		    fdsetind = 2;
		    break;

		    /*
		     * Get a timeout value in hundredths of a second
		     * (same units as KEYTIMEOUT).  0 means just poll.
		     * If not given, blocks indefinitely.
		     */
		case 't':
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (!idigit(*argptr)) {
			zwarnnam(nam, "number expected after -t");
			return 1;
		    }
		    tempnum = zstrtol(argptr, &endptr, 10);
		    if (*endptr) {
			zwarnnam(nam, "garbage after -t argument: %s",
				 endptr);
			return 1;
		    }
		    /* timevalue now active */
		    tvptr = &tv;
		    tv.tv_sec = (long)(tempnum / 100);
		    tv.tv_usec = (long)(tempnum % 100) * 10000L;

		    /* remember argptr is incremented at end of loop */
		    argptr = endptr - 1;
		    break;

		    /* Digits following option without arguments are fd's. */
		default:
		    if (handle_digits(nam, argptr, fdset+fdsetind,
				      &fdmax))
			return 1;
		}
	    }
	} else if (handle_digits(nam, argptr, fdset+fdsetind, &fdmax))
	    return 1;
    }

    errno = 0;
    do {
	i = select(fdmax, (SELECT_ARG_2_T)fdset, (SELECT_ARG_2_T)(fdset+1),
		   (SELECT_ARG_2_T)(fdset+2), tvptr);
    } while (i < 0 && errno == EINTR && !errflag);

    if (i <= 0) {
	if (i < 0)
	    zwarnnam(nam, "error on select: %e", errno);
	/* else no fd's set.  Presumably a timeout. */
	return 1;
    }

    /*
     * Make a linked list of all file descriptors which are ready.
     * These go into an array preceded by -r, -w or -e for read, write,
     * error as appropriate.  Typically there will only be one set
     * so this looks rather like overkill.
     */
    fdlist = znewlinklist();
    for (i = 0; i < 3; i++) {
	int doneit = 0;
	for (fd = 0; fd < fdmax; fd++) {
	    if (FD_ISSET(fd, fdset+i)) {
		char buf[BDIGBUFSIZE];
		if (outhash) {
		    /*
		     * Key/value pairs; keys are fd's (as strings),
		     * value is a (possibly improper) subset of "rwe".
		     */
		    LinkNode nptr;
		    int found = 0;

		    convbase(buf, fd, 10);
		    for (nptr = firstnode(fdlist); nptr; 
			 nptr = nextnode(nextnode(nptr))) {
			if (!strcmp((char *)getdata(nptr), buf)) {
			    /* Already there, add new character. */
			    void **dataptr = getaddrdata(nextnode(nptr));
			    char *data = (char *)*dataptr, *ptr;
			    found = 1;
			    if (!strchr(data, fdchar[i])) {
				strcpy(buf, data);
				for (ptr = buf; *ptr; ptr++)
				    ;
				*ptr++ = fdchar[i];
				*ptr = '\0';
				zsfree(data);
				*dataptr = ztrdup(buf);
			    }
			    break;
			}
		    }
		    if (!found) {
			/* Add new key/value pair. */
			zaddlinknode(fdlist, ztrdup(buf));
			buf[0] = fdchar[i];
			buf[1] = '\0';
			zaddlinknode(fdlist, ztrdup(buf));
		    }
		} else {
		    /* List of fd's preceded by -r, -w, -e. */
		    if (!doneit) {
			buf[0] = '-';
			buf[1] = fdchar[i];
			buf[2] = 0;
			zaddlinknode(fdlist, ztrdup(buf));
			doneit = 1;
		    }
		    convbase(buf, fd, 10);
		    zaddlinknode(fdlist, ztrdup(buf));
		}
	    }
	}
    }

    /* convert list to array */
    fdcount = countlinknodes(fdlist);
    outptr = outdata = (char **)zalloc((fdcount+1)*sizeof(char *));
    while (nonempty(fdlist))
	*outptr++ = getlinknode(fdlist);
    *outptr = NULL;
    /* and store in array parameter */
    if (outhash)
	sethparam(outhash, outdata);
    else
	setaparam(outarray, outdata);
    freelinklist(fdlist, NULL);

    return 0;
#else
    /* TODO: use poll */
    zerrnam(nam, "your system does not implement the select system call.");
    return 2;
#endif
}
示例#25
0
static int
raw_getbyte(long do_keytmout, char *cptr)
{
    int ret;
    struct ztmout tmout;
#if defined(HAS_TIO) && \
  (defined(sun) || (!defined(HAVE_POLL) && !defined(HAVE_SELECT)))
    struct ttyinfo ti;
#endif
#ifndef HAVE_POLL
# ifdef HAVE_SELECT
    fd_set foofd, errfd;
    FD_ZERO(&errfd);
# endif
#endif

    calc_timeout(&tmout, do_keytmout);

    /*
     * Handle timeouts and watched fd's.  If a watched fd or a function
     * timeout triggers we restart any key timeout.  This is likely to
     * be harmless: the combination is extremely rare and a function
     * is likely to occupy the user for a little while anyway.  We used
     * to make timeouts take precedence, but we can't now that the
     * timeouts may be external, so we may have both a permanent watched
     * fd and a long-term timeout.
     */
    if ((nwatch || tmout.tp != ZTM_NONE)) {
#if defined(HAVE_SELECT) || defined(HAVE_POLL)
	int i, errtry = 0, selret;
# ifdef HAVE_POLL
	int nfds;
	struct pollfd *fds;
# endif
# if defined(HAS_TIO) && defined(sun)
	/*
	 * Yes, I know this is complicated.  Yes, I know we
	 * already have three bits of code to poll the terminal
	 * down below.  No, I don't want to do this either.
	 * However, it turns out on certain OSes, specifically
	 * Solaris, that you can't poll typeahead for love nor
	 * money without actually trying to read it.  But
	 * if we are trying to select (and we need to if we
	 * are watching other fd's) we won't pick that up.
	 * So we just try and read it without blocking in
	 * the time-honoured (i.e. absurdly baroque) termios
	 * fashion.
	 */
	gettyinfo(&ti);
	ti.tio.c_cc[VMIN] = 0;
	settyinfo(&ti);
	winch_unblock();
	ret = read(SHTTY, cptr, 1);
	winch_block();
	ti.tio.c_cc[VMIN] = 1;
	settyinfo(&ti);
	if (ret > 0)
	    return 1;
# endif
# ifdef HAVE_POLL
	nfds = 1 + nwatch;
	/* First pollfd is SHTTY, following are the nwatch fds */
	fds = zalloc(sizeof(struct pollfd) * nfds);
	fds[0].fd = SHTTY;
	/*
	 * POLLIN, POLLIN, POLLIN,
	 * Keep those fd's POLLIN...
	 */
	fds[0].events = POLLIN;
	for (i = 0; i < nwatch; i++) {
	    fds[i+1].fd = watch_fds[i].fd;
	    fds[i+1].events = POLLIN;
	}
# endif
	for (;;) {
# ifdef HAVE_POLL
	    int poll_timeout;

	    if (tmout.tp != ZTM_NONE)
		poll_timeout = tmout.exp100ths * 10;
	    else
		poll_timeout = -1;

	    winch_unblock();
	    selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
	    winch_block();
# else
	    int fdmax = SHTTY;
	    struct timeval *tvptr;
	    struct timeval expire_tv;

	    FD_ZERO(&foofd);
	    FD_SET(SHTTY, &foofd);
	    if (!errtry) {
		for (i = 0; i < nwatch; i++) {
		    int fd = watch_fds[i].fd;
		    if (FD_ISSET(fd, &errfd))
			continue;
		    FD_SET(fd, &foofd);
		    if (fd > fdmax)
			fdmax = fd;
		}
	    }
	    FD_ZERO(&errfd);

	    if (tmout.tp != ZTM_NONE) {
		expire_tv.tv_sec = tmout.exp100ths / 100;
		expire_tv.tv_usec = (tmout.exp100ths % 100) * 10000L;
		tvptr = &expire_tv;
	    }
	    else
		tvptr = NULL;

	    winch_unblock();
	    selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
			    NULL, NULL, tvptr);
	    winch_block();
# endif
	    /*
	     * Make sure a user interrupt gets passed on straight away.
	     */
	    if (selret < 0 && (errflag || retflag || breaks || exit_pending))
		break;
	    /*
	     * Try to avoid errors on our special fd's from
	     * messing up reads from the terminal.  Try first
	     * with all fds, then try unsetting the special ones.
	     */
	    if (selret < 0 && !errtry) {
		errtry = 1;
		continue;
	    }
	    if (selret == 0) {
		/*
		 * Nothing ready and no error, so we timed out.
		 */
		switch (tmout.tp) {
		case ZTM_NONE:
		    /* keeps compiler happy if not debugging */
#ifdef DEBUG
		    dputs("BUG: timeout fired with no timeout set.");
#endif
		    /* treat as if a key timeout triggered */
		    /*FALLTHROUGH*/
		case ZTM_KEY:
		    /* Special value -2 signals nothing ready */
		    selret = -2;
		    break;

		case ZTM_FUNC:
		    while (firstnode(timedfns)) {
			Timedfn tfdat = (Timedfn)getdata(firstnode(timedfns));
			/*
			 * It's possible a previous function took
			 * a long time to run (though it can't
			 * call zle recursively), so recalculate
			 * the time on each iteration.
			 */
			time_t now = time(NULL);
			if (tfdat->when > now)
			    break;
			tfdat->func();
		    }
		    /* Function may have messed up the display */
		    if (resetneeded)
			zrefresh();
		    /* We need to recalculate the timeout */
		    /*FALLTHROUGH*/
		case ZTM_MAX:
		    /*
		     * Reached the limit of our range, but not the
		     * actual timeout; recalculate the timeout.
		     * We're cheating with the key timeout here:
		     * if one clashed with a function timeout we
		     * reconsider the key timeout from scratch.
		     * The effect of this is microscopic.
		     */
		    calc_timeout(&tmout, do_keytmout);
		    break;
		}
		/*
		 * If we handled the timeout successfully,
		 * carry on.
		 */
		if (selret == 0)
		    continue;
	    }
	    /* If error or unhandled timeout, give up. */
	    if (selret < 0)
		break;
	    /*
	     * If there's user input handle it straight away.
	     * This improves the user's ability to handle exceptional
	     * conditions like runaway output.
	     */
	    if (
# ifdef HAVE_POLL
		 (fds[0].revents & POLLIN)
# else
		 FD_ISSET(SHTTY, &foofd)
# endif
		 )
		break;
	    if (nwatch && !errtry) {
		/*
		 * Copy the details of the watch fds in case the
		 * user decides to delete one from inside the
		 * handler function.
		 */
		int lnwatch = nwatch;
		Watch_fd lwatch_fds = zalloc(lnwatch*sizeof(struct watch_fd));
		memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(struct watch_fd));
		for (i = 0; i < lnwatch; i++)
		    lwatch_fds[i].func = ztrdup(lwatch_fds[i].func);
		for (i = 0; i < lnwatch; i++) {
		    Watch_fd lwatch_fd = lwatch_fds + i;
		    if (
# ifdef HAVE_POLL
			(fds[i+1].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL))
# else
			FD_ISSET(lwatch_fd->fd, &foofd) ||
			FD_ISSET(lwatch_fd->fd, &errfd)
# endif
			) {
			/* Handle the fd. */
			char *fdbuf;
			{
			    char buf[BDIGBUFSIZE];
			    convbase(buf, lwatch_fd->fd, 10);
			    fdbuf = ztrdup(buf);
			}

			if (lwatch_fd->widget) {
			    zlecallhook(lwatch_fd->func, fdbuf);
			    zsfree(fdbuf);
			} else {
			    LinkList funcargs = znewlinklist();
			    zaddlinknode(funcargs, ztrdup(lwatch_fd->func));
			    zaddlinknode(funcargs, fdbuf);
# ifdef HAVE_POLL
#  ifdef POLLERR
			    if (fds[i+1].revents & POLLERR)
				zaddlinknode(funcargs, ztrdup("err"));
#  endif
#  ifdef POLLHUP
			    if (fds[i+1].revents & POLLHUP)
				zaddlinknode(funcargs, ztrdup("hup"));
#  endif
#  ifdef POLLNVAL
			    if (fds[i+1].revents & POLLNVAL)
				zaddlinknode(funcargs, ztrdup("nval"));
#  endif
# else
			    if (FD_ISSET(lwatch_fd->fd, &errfd))
				zaddlinknode(funcargs, ztrdup("err"));
# endif
			    callhookfunc(lwatch_fd->func, funcargs, 0, NULL);
			    freelinklist(funcargs, freestr);
			}
			if (errflag) {
			    /* No sensible way of handling errors here */
			    errflag &= ~ERRFLAG_ERROR;
			    /*
			     * Paranoia: don't run the hooks again this
			     * time.
			     */
			    errtry = 1;
			}
		    }
		}
		/* Function may have invalidated the display. */
		if (resetneeded)
		    zrefresh();
		for (i = 0; i < lnwatch; i++)
		    zsfree(lwatch_fds[i].func);
		zfree(lwatch_fds, lnwatch*sizeof(struct watch_fd));

# ifdef HAVE_POLL
		/* Function may have added or removed handlers */
		nfds = 1 + nwatch;
		if (nfds > 1) {
		    fds = zrealloc(fds, sizeof(struct pollfd) * nfds);
		    for (i = 0; i < nwatch; i++) {
			/*
			 * This is imperfect because it assumes fds[] and
			 * watch_fds[] remain in sync, which may be false
			 * if handlers are shuffled.  However, it should
			 * be harmless (e.g., produce one extra pass of
			 * the loop) in the event they fall out of sync.
			 */
			if (fds[i+1].fd == watch_fds[i].fd &&
			    (fds[i+1].revents & (POLLERR|POLLHUP|POLLNVAL))) {
			    fds[i+1].events = 0;	/* Don't poll this */
			} else {
			    fds[i+1].fd = watch_fds[i].fd;
			    fds[i+1].events = POLLIN;
			}
			fds[i+1].revents = 0;
		    }
		}
# endif
	    }
	}
# ifdef HAVE_POLL
	zfree(fds, sizeof(struct pollfd) * nfds);
# endif
	if (selret < 0)
	    return selret;
#else
# ifdef HAS_TIO
	ti = shttyinfo;
	ti.tio.c_lflag &= ~ICANON;
	ti.tio.c_cc[VMIN] = 0;
	ti.tio.c_cc[VTIME] = tmout.exp100ths / 10;
#  ifdef HAVE_TERMIOS_H
	tcsetattr(SHTTY, TCSANOW, &ti.tio);
#  else
	ioctl(SHTTY, TCSETA, &ti.tio);
#  endif
	winch_unblock();
	ret = read(SHTTY, cptr, 1);
	winch_block();
#  ifdef HAVE_TERMIOS_H
	tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
#  else
	ioctl(SHTTY, TCSETA, &shttyinfo.tio);
#  endif
	return (ret <= 0) ? ret : *cptr;
# endif
#endif
    }

    winch_unblock();
    ret = read(SHTTY, cptr, 1);
    winch_block();

    return ret;
}
示例#26
0
int
getvisrchstr(void)
{
    char *sbuf = halloc(80);
    int sptr = 1, ret = 0, ssbuf = 80;
    int cmd;
    int *obindtab = bindtab;

    if (visrchstr) {
	zsfree(visrchstr);
	visrchstr = NULL;
    }
    clearlist = 1;
    statusline = sbuf;
    sbuf[0] = (visrchsense == -1) ? '?' : '/';
    bindtab = mainbindtab;
    while (sptr) {
	sbuf[sptr] = '_';
	statusll = sptr + 1;
	refresh();
	if ((cmd = getkeycmd()) < 0 || cmd == z_sendbreak) {
	    ret = 0;
	    break;
	}
	if(cmd == z_magicspace) {
	    c = ' ';
	    cmd = z_selfinsert;
	}
	switch(cmd) {
	  case z_redisplay:
	    redisplay();
	    break;
	  case z_clearscreen:
	    clearscreen();
	    break;
	  case z_acceptline:
	  case z_vicmdmode:
	    sbuf[sptr] = 0;
	    visrchstr = metafy(sbuf + 1, sptr - 1, META_DUP);
	    ret = 1;
	    sptr = 0;
	    break;
	  case z_backwarddeletechar:
	  case z_vibackwarddeletechar:
	    sptr--;
	    break;
	  case z_backwardkillword:
	  case z_vibackwardkillword:
	    while(sptr != 1 && iblank(sbuf[sptr - 1]))
		sptr--;
	    if(iident(sbuf[sptr - 1]))
		while(sptr != 1 && iident(sbuf[sptr - 1]))
		    sptr--;
	    else
		while(sptr != 1 && !iident(sbuf[sptr - 1]) && !iblank(sbuf[sptr - 1]))
		    sptr--;
	    break;
	  case z_sendstring:
	    sendstring();
	    break;
	  case z_viquotedinsert:
	    sbuf[sptr] = '^';
	    refresh();
	    /* fall through */
	  case z_quotedinsert:
	    if ((c = getkey(0)) == EOF) {
		feep();
		break;
	    }
	    goto ins;
	  case z_selfinsertunmeta:
	    c &= 0x7f;
	    if(c == '\r')
		c = '\n';
	  case z_selfinsert:
	  ins:
	    if(sptr == ssbuf - 1) {
		char *newbuf = halloc(ssbuf *= 2);
		strcpy(newbuf, sbuf);
		statusline = sbuf = newbuf;
	    }
	    sbuf[sptr++] = c;
	    break;
	  default:
	    feep();
	}
    }
    statusline = NULL;
    bindtab = obindtab;
    return ret;
}
示例#27
0
文件: complete.c 项目: Jaharmi/zsh
static int
bin_compadd(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
{
    struct cadata dat;
    char *p, **sp, *e, *m = NULL, *mstr = NULL;
    int dm;
    Cmatcher match = NULL;

    if (incompfunc != 1) {
	zwarnnam(name, "can only be called from completion function");
	return 1;
    }
    dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = dat.mesg =
	dat.pre = dat.suf = dat.group = dat.rems = dat.remf = dat.disp = 
	dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
    dat.match = NULL;
    dat.flags = 0;
    dat.aflags = CAF_MATCH;
    dat.dummies = 0;

    for (; *argv && **argv ==  '-'; argv++) {
	if (!(*argv)[1]) {
	    argv++;
	    break;
	}
	for (p = *argv + 1; *p; p++) {
	    sp = NULL;
	    e = NULL;
	    dm = 0;
	    switch (*p) {
	    case 'q':
		dat.flags |= CMF_REMOVE;
		break;
	    case 'Q':
		dat.aflags |= CAF_QUOTE;
		break;
	    case 'C':
		dat.aflags |= CAF_ALL;
		break;
	    case 'f':
		dat.flags |= CMF_FILE;
		break;
	    case 'e':
		dat.flags |= CMF_ISPAR;
		break;
	    case 'a':
		dat.aflags |= CAF_ARRAYS;
		break;
	    case 'k':
		dat.aflags |= CAF_ARRAYS|CAF_KEYS;
		break;
	    case 'F':
		sp = &(dat.ign);
		e = "string expected after -%c";
		break;
	    case 'n':
		dat.flags |= CMF_NOLIST;
		break;
	    case 'U':
		dat.aflags &= ~CAF_MATCH;
		break;
	    case 'P':
		sp = &(dat.pre);
		e = "string expected after -%c";
		break;
	    case 'S':
		sp = &(dat.suf);
		e = "string expected after -%c";
		break;
	    case 'J':
		sp = &(dat.group);
		e = "group name expected after -%c";
		break;
	    case 'V':
		if (!dat.group)
		    dat.aflags |= CAF_NOSORT;
		sp = &(dat.group);
		e = "group name expected after -%c";
		break;
	    case '1':
		if (!(dat.aflags & CAF_UNIQCON))
		    dat.aflags |= CAF_UNIQALL;
		break;
	    case '2':
		if (!(dat.aflags & CAF_UNIQALL))
		    dat.aflags |= CAF_UNIQCON;
		break;
	    case 'i':
		sp = &(dat.ipre);
		e = "string expected after -%c";
		break;
	    case 'I':
		sp = &(dat.isuf);
		e = "string expected after -%c";
		break;
	    case 'p':
		sp = &(dat.ppre);
		e = "string expected after -%c";
		break;
	    case 's':
		sp = &(dat.psuf);
		e = "string expected after -%c";
		break;
	    case 'W':
		sp = &(dat.prpre);
		e = "string expected after -%c";
		break;
	    case 'M':
		sp = &m;
		e = "matching specification expected after -%c";
		dm = 1;
		break;
	    case 'X':
		sp = &(dat.exp);
		e = "string expected after -%c";
		break;
	    case 'x':
		sp = &(dat.mesg);
		e = "string expected after -%c";
		break;
	    case 'r':
		dat.flags |= CMF_REMOVE;
		sp = &(dat.rems);
		e = "string expected after -%c";
		break;
	    case 'R':
		dat.flags |= CMF_REMOVE;
		sp = &(dat.remf);
		e = "function name expected after -%c";
		break;
	    case 'A':
		sp = &(dat.apar);
		e = "parameter name expected after -%c";
		break;
	    case 'O':
		sp = &(dat.opar);
		e = "parameter name expected after -%c";
		break;
	    case 'D':
		sp = &(dat.dpar);
		e = "parameter name expected after -%c";
		break;
	    case 'd':
		sp = &(dat.disp);
		e = "parameter name expected after -%c";
		break;
	    case 'l':
		dat.flags |= CMF_DISPLINE;
		break;
	    case 'o':
		dat.flags |= CMF_MORDER;
		break;
	    case 'E':
                if (p[1]) {
                    dat.dummies = atoi(p + 1);
                    p = "" - 1;
                } else if (argv[1]) {
                    argv++;
                    dat.dummies = atoi(*argv);
                    p = "" - 1;
                } else {
                    zwarnnam(name, "number expected after -%c", *p);
		    zsfree(mstr);
                    return 1;
                }
                if (dat.dummies < 0) {
                    zwarnnam(name, "invalid number: %d", dat.dummies);
		    zsfree(mstr);
                    return 1;
                }
		break;
	    case '-':
		argv++;
		goto ca_args;
	    default:
		zwarnnam(name, "bad option: -%c", *p);
		zsfree(mstr);
		return 1;
	    }
	    if (sp) {
		if (p[1]) {
		    if (!*sp)
			*sp = p + 1;
		    p = "" - 1;
		} else if (argv[1]) {
		    argv++;
		    if (!*sp)
			*sp = *argv;
		    p = "" - 1;
		} else {
		    zwarnnam(name, e, *p);
		    zsfree(mstr);
		    return 1;
		}
		if (dm) {
		    if (mstr) {
			char *tmp = tricat(mstr, " ", m);
			zsfree(mstr);
			mstr = tmp;
		    } else
			mstr = ztrdup(m);
		    m = NULL;
		}
	    }
	}
    }

 ca_args:

    if (mstr && (match = parse_cmatcher(name, mstr)) == pcm_err) {
	zsfree(mstr);
	return 1;
    }
    zsfree(mstr);

    if (!*argv && !dat.group && !dat.mesg &&
	!(dat.aflags & (CAF_NOSORT|CAF_UNIQALL|CAF_UNIQCON|CAF_ALL)))
	return 1;

    dat.match = match = cpcmatcher(match);
    dm = addmatches(&dat, argv);
    freecmatcher(match);

    return dm;
}
示例#28
0
文件: complete.c 项目: Jaharmi/zsh
int
finish_(UNUSED(Module m))
{
    if (compwords)
	freearray(compwords);
    if (compredirs)
	freearray(compredirs);
    zsfree(compprefix);
    zsfree(compsuffix);
    zsfree(complastprefix);
    zsfree(complastsuffix);
    zsfree(compiprefix);
    zsfree(compisuffix);
    zsfree(compqiprefix);
    zsfree(compqisuffix);
    zsfree(compcontext);
    zsfree(compparameter);
    zsfree(compredirect);
    zsfree(compquote);
    zsfree(compqstack);
    zsfree(compquoting);
    zsfree(comprestore);
    zsfree(complist);
    zsfree(compinsert);
    zsfree(compexact);
    zsfree(compexactstr);
    zsfree(comppatmatch);
    zsfree(comppatinsert);
    zsfree(complastprompt);
    zsfree(comptoend);
    zsfree(compoldlist);
    zsfree(compoldins);
    zsfree(compvared);

    hascompmod = 0;

    return 0;
}
示例#29
0
文件: complete.c 项目: Jaharmi/zsh
static int
comp_wrapper(Eprog prog, FuncWrap w, char *name)
{
    if (incompfunc != 1)
	return 1;
    else {
	char *orest, *opre, *osuf, *oipre, *oisuf, **owords, **oredirs;
	char *oqipre, *oqisuf, *oq, *oqi, *oqs, *oaq;
	zlong ocur;
	unsigned int runset = 0, kunset = 0, m, sm;
	Param *pp;

	m = CP_WORDS | CP_REDIRS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | 
	    CP_IPREFIX | CP_ISUFFIX | CP_QIPREFIX | CP_QISUFFIX;
	for (pp = comprpms, sm = 1; m; pp++, m >>= 1, sm <<= 1) {
	    if ((m & 1) && ((*pp)->node.flags & PM_UNSET))
		runset |= sm;
	}
	if (compkpms[CPN_RESTORE]->node.flags & PM_UNSET)
	    kunset = CP_RESTORE;
	orest = comprestore;
	comprestore = ztrdup("auto");
	ocur = compcurrent;
	opre = ztrdup(compprefix);
	osuf = ztrdup(compsuffix);
	oipre = ztrdup(compiprefix);
	oisuf = ztrdup(compisuffix);
	oqipre = ztrdup(compqiprefix);
	oqisuf = ztrdup(compqisuffix);
	oq = ztrdup(compquote);
	oqi = ztrdup(compquoting);
	oqs = ztrdup(compqstack);
	oaq = ztrdup(autoq);
	owords = zarrdup(compwords);
	oredirs = zarrdup(compredirs);

	runshfunc(prog, w, name);

	if (comprestore && !strcmp(comprestore, "auto")) {
	    compcurrent = ocur;
	    zsfree(compprefix);
	    compprefix = opre;
	    zsfree(compsuffix);
	    compsuffix = osuf;
	    zsfree(compiprefix);
	    compiprefix = oipre;
	    zsfree(compisuffix);
	    compisuffix = oisuf;
	    zsfree(compqiprefix);
	    compqiprefix = oqipre;
	    zsfree(compqisuffix);
	    compqisuffix = oqisuf;
	    zsfree(compquote);
	    compquote = oq;
	    zsfree(compquoting);
	    compquoting = oqi;
	    zsfree(compqstack);
	    compqstack = oqs;
	    zsfree(autoq);
	    autoq = oaq;
	    freearray(compwords);
	    freearray(compredirs);
	    compwords = owords;
            compredirs = oredirs;
	    comp_setunset(CP_COMPSTATE |
			  (~runset & (CP_WORDS | CP_REDIRS |
                                      CP_CURRENT | CP_PREFIX |
                                      CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX |
                                      CP_QIPREFIX | CP_QISUFFIX)),
			  (runset & CP_ALLREALS),
			  (~kunset & CP_RESTORE), (kunset & CP_ALLKEYS));
	} else {
	    comp_setunset(CP_COMPSTATE, 0, (~kunset & CP_RESTORE),
			  (kunset & CP_RESTORE));
	    zsfree(opre);
	    zsfree(osuf);
	    zsfree(oipre);
	    zsfree(oisuf);
	    zsfree(oqipre);
	    zsfree(oqisuf);
	    zsfree(oq);
	    zsfree(oqi);
	    zsfree(oqs);
	    zsfree(oaq);
	    freearray(owords);
	    freearray(oredirs);
	}
	zsfree(comprestore);
	comprestore = orest;

	return 0;
    }
}
示例#30
0
文件: init.c 项目: 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;
    }