Exemple #1
0
static void
texpand(struct table *tp, int nsize)
{
    int i;
    struct tbl *tblp, **p;
    struct tbl **ntblp, **otblp = tp->tbls;
    int osize = tp->size;

    ntblp = areallocarray(NULL, nsize, sizeof(struct tbl *), tp->areap);
    for (i = 0; i < nsize; i++)
        ntblp[i] = NULL;
    tp->size = nsize;
    tp->nfree = 7*nsize/10;	/* table can get 70% full */
    tp->tbls = ntblp;
    if (otblp == NULL)
        return;
    for (i = 0; i < osize; i++)
        if ((tblp = otblp[i]) != NULL) {
            if ((tblp->flag&DEFINED)) {
                for (p = &ntblp[hash(tblp->name) &
                                (tp->size-1)]; *p != NULL; p--)
                    if (p == ntblp) /* wrap */
                        p += tp->size;
                *p = tblp;
                tp->nfree--;
            } else if (!(tblp->flag & FINUSE)) {
                afree(tblp, tp->areap);
            }
        }
    afree(otblp, tp->areap);
}
Exemple #2
0
static int
x_command_glob(int flags, const char *str, int slen, char ***wordsp)
{
	char *toglob;
	char *pat;
	char *fpath;
	int nwords;
	XPtrV w;
	struct block *l;

	if (slen < 0)
		return 0;

	toglob = add_glob(str, slen);

	/* Convert "foo*" (toglob) to a pattern for future use */
	pat = evalstr(toglob, DOPAT|DOTILDE);
	afree(toglob, ATEMP);

	XPinit(w, 32);

	glob_table(pat, &w, &keywords);
	glob_table(pat, &w, &aliases);
	glob_table(pat, &w, &builtins);
	for (l = e->loc; l; l = l->next)
		glob_table(pat, &w, &l->funs);

	glob_path(flags, pat, &w, path);
	if ((fpath = str_val(global("FPATH"))) != null)
		glob_path(flags, pat, &w, fpath);

	nwords = XPsize(w);

	if (!nwords) {
		*wordsp = NULL;
		XPfree(w);
		return 0;
	}

	/* Sort entries */
	if (flags & XCF_FULLPATH) {
		/* Sort by basename, then path order */
		struct path_order_info *info;
		struct path_order_info *last_info = NULL;
		char **words = (char **) XPptrv(w);
		int path_order = 0;
		int i;

		info = areallocarray(NULL, nwords,
		    sizeof(struct path_order_info), ATEMP);

		for (i = 0; i < nwords; i++) {
			info[i].word = words[i];
			info[i].base = x_basename(words[i], NULL);
			if (!last_info || info[i].base != last_info->base ||
			    strncmp(words[i], last_info->word, info[i].base) != 0) {
				last_info = &info[i];
				path_order++;
			}
			info[i].path_order = path_order;
		}
		qsort(info, nwords, sizeof(struct path_order_info),
			path_order_cmp);
		for (i = 0; i < nwords; i++)
			words[i] = info[i].word;
		afree(info, ATEMP);
	} else {
		/* Sort and remove duplicate entries */
		char **words = (char **) XPptrv(w);
		int i, j;

		qsortp(XPptrv(w), (size_t) nwords, xstrcmp);

		for (i = j = 0; i < nwords - 1; i++) {
			if (strcmp(words[i], words[i + 1]))
				words[j++] = words[i];
			else
				afree(words[i], ATEMP);
		}
		words[j++] = words[i];
		nwords = j;
		w.cur = (void **) &words[j];
	}

	XPput(w, NULL);
	*wordsp = (char **) XPclose(w);

	return nwords;
}
Exemple #3
0
static int
x_try_array(const char *buf, int buflen, const char *want, int wantlen,
    int *nwords, char ***words)
{
	const char *cmd, *cp;
	int cmdlen, n, i, slen;
	char *name, *s;
	struct tbl *v, *vp;

	*nwords = 0;
	*words = NULL;

	/* Walk back to find start of command. */
	if (want == buf)
		return 0;
	for (cmd = want; cmd > buf; cmd--) {
		if (strchr(";|&()`", cmd[-1]) != NULL)
			break;
	}
	while (cmd < want && isspace((u_char)*cmd))
		cmd++;
	cmdlen = 0;
	while (cmd + cmdlen < want && !isspace((u_char)cmd[cmdlen]))
		cmdlen++;
	for (i = 0; i < cmdlen; i++) {
		if (!isalnum((u_char)cmd[i]) && cmd[i] != '_')
			return 0;
	}

	/* Take a stab at argument count from here. */
	n = 1;
	for (cp = cmd + cmdlen + 1; cp < want; cp++) {
		if (!isspace((u_char)cp[-1]) && isspace((u_char)*cp))
			n++;
	}

	/* Try to find the array. */
	if (asprintf(&name, "complete_%.*s_%d", cmdlen, cmd, n) < 0)
		internal_errorf("unable to allocate memory");
	v = global(name);
	free(name);
	if (~v->flag & (ISSET|ARRAY)) {
		if (asprintf(&name, "complete_%.*s", cmdlen, cmd) < 0)
			internal_errorf("unable to allocate memory");
		v = global(name);
		free(name);
		if (~v->flag & (ISSET|ARRAY))
			return 0;
	}

	/* Walk the array and build words list. */
	for (vp = v; vp; vp = vp->u.array) {
		if (~vp->flag & ISSET)
			continue;

		s = str_val(vp);
		slen = strlen(s);

		if (slen < wantlen)
			continue;
		if (slen > wantlen)
			slen = wantlen;
		if (slen != 0 && strncmp(s, want, slen) != 0)
			continue;

		*words = areallocarray(*words, (*nwords) + 2, sizeof **words,
		    ATEMP);
		(*words)[(*nwords)++] = str_save(s, ATEMP);
	}
	if (*nwords != 0)
		(*words)[*nwords] = NULL;

	return *nwords != 0;
}