about summary refs log tree commit diff
path: root/Src/Zle/comp1.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/comp1.c')
-rw-r--r--Src/Zle/comp1.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c
new file mode 100644
index 000000000..acd1288a6
--- /dev/null
+++ b/Src/Zle/comp1.c
@@ -0,0 +1,291 @@
+/*
+ * comp1.c - base of the completion system
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1992-1997 Paul Falstad
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Paul Falstad or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Paul Falstad and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Paul Falstad and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose.  The software
+ * provided hereunder is on an "as is" basis, and Paul Falstad and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "comp1.mdh"
+
+#include "comp1.pro"
+
+/* default completion infos */
+ 
+/**/
+struct compctl cc_compos, cc_default, cc_first, cc_dummy;
+ 
+/* hash table for completion info for commands */
+ 
+/**/
+HashTable compctltab;
+
+/* Words on the command line, for use in completion */
+ 
+/**/
+int clwsize, clwnum, clwpos;
+/**/
+char **clwords;
+
+/* != 0 if in a shell function called from completion, such that read -[cl]  *
+ * will work (i.e., the line is metafied, and the above word arrays are OK). */
+
+/**/
+int incompctlfunc;
+
+/**/
+static void
+createcompctltable(void)
+{
+    compctltab = newhashtable(23, "compctltab", NULL);
+
+    compctltab->hash        = hasher;
+    compctltab->emptytable  = emptyhashtable;
+    compctltab->filltable   = NULL;
+    compctltab->addnode     = addhashnode;
+    compctltab->getnode     = gethashnode2;
+    compctltab->getnode2    = gethashnode2;
+    compctltab->removenode  = removehashnode;
+    compctltab->disablenode = NULL;
+    compctltab->enablenode  = NULL;
+    compctltab->freenode    = freecompctlp;
+    compctltab->printnode   = NULL;
+}
+
+/**/
+static void
+freecompctlp(HashNode hn)
+{
+    Compctlp ccp = (Compctlp) hn;
+
+    zsfree(ccp->nam);
+    freecompctl(ccp->cc);
+    zfree(ccp, sizeof(struct compctlp));
+}
+
+/**/
+void
+freecompctl(Compctl cc)
+{
+    if (cc == &cc_default ||
+ 	cc == &cc_first ||
+	cc == &cc_compos ||
+	--cc->refc > 0)
+	return;
+
+    zsfree(cc->keyvar);
+    zsfree(cc->glob);
+    zsfree(cc->str);
+    zsfree(cc->func);
+    zsfree(cc->explain);
+    zsfree(cc->ylist);
+    zsfree(cc->prefix);
+    zsfree(cc->suffix);
+    zsfree(cc->hpat);
+    zsfree(cc->subcmd);
+    if (cc->cond)
+	freecompcond(cc->cond);
+    if (cc->ext) {
+	Compctl n, m;
+
+	n = cc->ext;
+	do {
+	    m = (Compctl) (n->next);
+	    freecompctl(n);
+	    n = m;
+	}
+	while (n);
+    }
+    if (cc->xor && cc->xor != &cc_default)
+	freecompctl(cc->xor);
+    zfree(cc, sizeof(struct compctl));
+}
+
+/**/
+void
+freecompcond(void *a)
+{
+    Compcond cc = (Compcond) a;
+    Compcond and, or, c;
+    int n;
+
+    for (c = cc; c; c = or) {
+	or = c->or;
+	for (; c; c = and) {
+	    and = c->and;
+	    if (c->type == CCT_POS ||
+		c->type == CCT_NUMWORDS) {
+		free(c->u.r.a);
+		free(c->u.r.b);
+	    } else if (c->type == CCT_CURSUF ||
+		       c->type == CCT_CURPRE) {
+		for (n = 0; n < c->n; n++)
+		    if (c->u.s.s[n])
+			zsfree(c->u.s.s[n]);
+		free(c->u.s.s);
+	    } else if (c->type == CCT_RANGESTR ||
+		       c->type == CCT_RANGEPAT) {
+		for (n = 0; n < c->n; n++)
+		    if (c->u.l.a[n])
+			zsfree(c->u.l.a[n]);
+		free(c->u.l.a);
+		for (n = 0; n < c->n; n++)
+		    if (c->u.l.b[n])
+			zsfree(c->u.l.b[n]);
+		free(c->u.l.b);
+	    } else {
+		for (n = 0; n < c->n; n++)
+		    if (c->u.s.s[n])
+			zsfree(c->u.s.s[n]);
+		free(c->u.s.p);
+		free(c->u.s.s);
+	    }
+	    zfree(c, sizeof(struct compcond));
+	}
+    }
+}
+
+/**/
+int
+compctlread(char *name, char **args, char *ops, char *reply)
+{
+    char *buf, *bptr;
+
+    /* only allowed to be called for completion */
+    if (!incompctlfunc) {
+	zwarnnam(name, "option valid only in functions called for completion",
+		NULL, 0);
+	return 1;
+    }
+
+    if (ops['l']) {
+	/* -ln gives the index of the word the cursor is currently on, which is
+	available in cs (but remember that Zsh counts from one, not zero!) */
+	if (ops['n']) {
+	    char nbuf[14];
+
+	    if (ops['e'] || ops['E'])
+		printf("%d\n", cs + 1);
+	    if (!ops['e']) {
+		sprintf(nbuf, "%d", cs + 1);
+		setsparam(reply, ztrdup(nbuf));
+	    }
+	    return 0;
+	}
+	/* without -n, the current line is assigned to the given parameter as a
+	scalar */
+	if (ops['e'] || ops['E']) {
+	    zputs((char *) line, stdout);
+	    putchar('\n');
+	}
+	if (!ops['e'])
+	    setsparam(reply, ztrdup((char *) line));
+    } else {
+	int i;
+
+	/* -cn gives the current cursor position within the current word, which
+	is available in clwpos (but remember that Zsh counts from one, not
+	zero!) */
+	if (ops['n']) {
+	    char nbuf[14];
+
+	    if (ops['e'] || ops['E'])
+		printf("%d\n", clwpos + 1);
+	    if (!ops['e']) {
+		sprintf(nbuf, "%d", clwpos + 1);
+		setsparam(reply, ztrdup(nbuf));
+	    }
+	    return 0;
+	}
+	/* without -n, the words of the current line are assigned to the given
+	parameters separately */
+	if (ops['A'] && !ops['e']) {
+	    /* the -A option means that one array is specified, instead of
+	    many parameters */
+	    char **p, **b = (char **)zcalloc((clwnum + 1) * sizeof(char *));
+
+	    for (i = 0, p = b; i < clwnum; p++, i++)
+		*p = ztrdup(clwords[i]);
+
+	    setaparam(reply, b);
+	    return 0;
+	}
+	if (ops['e'] || ops['E']) {
+	    for (i = 0; i < clwnum; i++) {
+		zputs(clwords[i], stdout);
+		putchar('\n');
+	    }
+
+	    if (ops['e'])
+		return 0;
+	}
+
+	for (i = 0; i < clwnum && *args; reply = *args++, i++)
+	    setsparam(reply, ztrdup(clwords[i]));
+
+	if (i < clwnum) {
+	    int j, len;
+
+	    for (j = i, len = 0; j < clwnum; len += strlen(clwords[j++]));
+	    bptr = buf = zalloc(len + j - i);
+	    while (i < clwnum) {
+		strucpy(&bptr, clwords[i++]);
+		*bptr++ = ' ';
+	    }
+	    bptr[-1] = '\0';
+	} else
+	    buf = ztrdup("");
+	setsparam(reply, buf);
+    }
+    return 0;
+}
+
+/**/
+int
+boot_comp1(Module m)
+{
+    compctlreadptr = compctlread;
+    clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));
+    createcompctltable();
+    cc_compos.mask = CC_COMMPATH;
+    cc_default.refc = 10000;
+    cc_default.mask = CC_FILES;
+    cc_first.refc = 10000;
+    cc_first.mask = 0;
+    return 0;
+}
+
+#ifdef MODULE
+
+/**/
+int
+cleanup_comp1(Module m)
+{
+    deletehashtable(compctltab);
+    zfree(clwords, clwsize * sizeof(char *));
+    compctlreadptr = fallback_compctlread;
+    return 0;
+}
+
+#endif /* MODULE */