diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:05:35 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:05:35 +0000 |
commit | 32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3 (patch) | |
tree | 212c29fe244d0222bab8efe3032e7fa965842945 /Src/Zle/comp1.c | |
parent | c175751b501a3a4cb40ad4787340a597ea769be4 (diff) | |
download | zsh-32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3.tar.gz zsh-32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3.tar.xz zsh-32c2ebbaa5d7927f33ee0ecf98472a71cf902cf3.zip |
zsh-3.1.5 zsh-3.1.5
Diffstat (limited to 'Src/Zle/comp1.c')
-rw-r--r-- | Src/Zle/comp1.c | 291 |
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 */ |