1/*
2 * compctl.c - the compctl builtin
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1992-1997 Paul Falstad
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30#include "compctl.mdh"
31#include "compctl.pro"
32
33/* Global matcher. */
34
35/**/
36static Cmlist cmatcher;
37
38/* Default completion infos */
39
40/**/
41struct compctl cc_compos, cc_default, cc_first, cc_dummy;
42
43/* Hash table for completion info for commands */
44
45/**/
46HashTable compctltab;
47
48/* List of pattern compctls */
49
50/**/
51Patcomp patcomps;
52
53#define COMP_LIST	(1<<0)	/* -L */
54#define COMP_COMMAND	(1<<1)	/* -C */
55#define COMP_DEFAULT	(1<<2)	/* -D */
56#define COMP_FIRST	(1<<3)	/* -T */
57#define COMP_REMOVE	(1<<4)
58#define COMP_LISTMATCH	(1<<5)	/* -L and -M */
59
60#define COMP_SPECIAL (COMP_COMMAND|COMP_DEFAULT|COMP_FIRST)
61
62/* Flag for listing, command, default, or first completion */
63static int cclist;
64
65/* Mask for determining what to print */
66static unsigned long showmask = 0;
67
68/**/
69static void
70createcompctltable(void)
71{
72    compctltab = newhashtable(23, "compctltab", NULL);
73
74    compctltab->hash        = hasher;
75    compctltab->emptytable  = emptyhashtable;
76    compctltab->filltable   = NULL;
77    compctltab->cmpnodes    = strcmp;
78    compctltab->addnode     = addhashnode;
79    compctltab->getnode     = gethashnode2;
80    compctltab->getnode2    = gethashnode2;
81    compctltab->removenode  = removehashnode;
82    compctltab->disablenode = NULL;
83    compctltab->enablenode  = NULL;
84    compctltab->freenode    = freecompctlp;
85    compctltab->printnode   = printcompctlp;
86
87    patcomps = NULL;
88}
89
90/**/
91static void
92freecompctlp(HashNode hn)
93{
94    Compctlp ccp = (Compctlp) hn;
95
96    zsfree(ccp->node.nam);
97    freecompctl(ccp->cc);
98    zfree(ccp, sizeof(struct compctlp));
99}
100
101/**/
102void
103freecompctl(Compctl cc)
104{
105    if (cc == &cc_default ||
106 	cc == &cc_first ||
107	cc == &cc_compos ||
108	--cc->refc > 0)
109	return;
110
111    zsfree(cc->keyvar);
112    zsfree(cc->glob);
113    zsfree(cc->str);
114    zsfree(cc->func);
115    zsfree(cc->explain);
116    zsfree(cc->ylist);
117    zsfree(cc->prefix);
118    zsfree(cc->suffix);
119    zsfree(cc->hpat);
120    zsfree(cc->gname);
121    zsfree(cc->subcmd);
122    zsfree(cc->substr);
123    if (cc->cond)
124	freecompcond(cc->cond);
125    if (cc->ext) {
126	Compctl n, m;
127
128	n = cc->ext;
129	do {
130	    m = (Compctl) (n->next);
131	    freecompctl(n);
132	    n = m;
133	}
134	while (n);
135    }
136    if (cc->xor && cc->xor != &cc_default)
137	freecompctl(cc->xor);
138    if (cc->matcher)
139	freecmatcher(cc->matcher);
140    zsfree(cc->mstr);
141    zfree(cc, sizeof(struct compctl));
142}
143
144/**/
145void
146freecompcond(void *a)
147{
148    Compcond cc = (Compcond) a;
149    Compcond and, or, c;
150    int n;
151
152    for (c = cc; c; c = or) {
153	or = c->or;
154	for (; c; c = and) {
155	    and = c->and;
156	    if (c->type == CCT_POS ||
157		c->type == CCT_NUMWORDS) {
158		free(c->u.r.a);
159		free(c->u.r.b);
160	    } else if (c->type == CCT_CURSUF ||
161		       c->type == CCT_CURPRE) {
162		for (n = 0; n < c->n; n++)
163		    if (c->u.s.s[n])
164			zsfree(c->u.s.s[n]);
165		free(c->u.s.s);
166	    } else if (c->type == CCT_RANGESTR ||
167		       c->type == CCT_RANGEPAT) {
168		for (n = 0; n < c->n; n++)
169		    if (c->u.l.a[n])
170			zsfree(c->u.l.a[n]);
171		free(c->u.l.a);
172		for (n = 0; n < c->n; n++)
173		    if (c->u.l.b[n])
174			zsfree(c->u.l.b[n]);
175		free(c->u.l.b);
176	    } else {
177		for (n = 0; n < c->n; n++)
178		    if (c->u.s.s[n])
179			zsfree(c->u.s.s[n]);
180		free(c->u.s.p);
181		free(c->u.s.s);
182	    }
183	    zfree(c, sizeof(struct compcond));
184	}
185    }
186}
187
188/**/
189int
190compctlread(char *name, char **args, Options ops, char *reply)
191{
192    char *buf, *bptr;
193
194    /* only allowed to be called for completion */
195    if (!incompctlfunc) {
196	zwarnnam(name, "option valid only in functions called for completion");
197	return 1;
198    }
199
200    METACHECK();
201
202    if (OPT_ISSET(ops,'l')) {
203	/*
204	 * -ln gives the index of the word the cursor is currently on, which
205	 * is available in zlemetacs (but remember that Zsh counts from one,
206	 * not zero!)
207	 */
208	if (OPT_ISSET(ops,'n')) {
209	    char nbuf[14];
210
211	    if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
212		printf("%d\n", zlemetacs + 1);
213	    if (!OPT_ISSET(ops,'e')) {
214		sprintf(nbuf, "%d", zlemetacs + 1);
215		setsparam(reply, ztrdup(nbuf));
216	    }
217	    return 0;
218	}
219	/* without -n, the current line is assigned to the given parameter as a
220	scalar */
221	if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
222	    zputs(zlemetaline, stdout);
223	    putchar('\n');
224	}
225	if (!OPT_ISSET(ops,'e'))
226	    setsparam(reply, ztrdup(zlemetaline));
227    } else {
228	int i;
229
230	/* -cn gives the current cursor position within the current word, which
231	is available in clwpos (but remember that Zsh counts from one, not
232	zero!) */
233	if (OPT_ISSET(ops,'n')) {
234	    char nbuf[14];
235
236	    if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
237		printf("%d\n", clwpos + 1);
238	    if (!OPT_ISSET(ops,'e')) {
239		sprintf(nbuf, "%d", clwpos + 1);
240		setsparam(reply, ztrdup(nbuf));
241	    }
242	    return 0;
243	}
244	/* without -n, the words of the current line are assigned to the given
245	parameters separately */
246	if (OPT_ISSET(ops,'A') && !OPT_ISSET(ops,'e')) {
247	    /* the -A option means that one array is specified, instead of
248	    many parameters */
249	    char **p, **b = (char **)zshcalloc((clwnum + 1) * sizeof(char *));
250
251	    for (i = 0, p = b; i < clwnum; p++, i++)
252		*p = ztrdup(clwords[i]);
253
254	    setaparam(reply, b);
255	    return 0;
256	}
257	if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
258	    for (i = 0; i < clwnum; i++) {
259		zputs(clwords[i], stdout);
260		putchar('\n');
261	    }
262
263	    if (OPT_ISSET(ops,'e'))
264		return 0;
265	}
266
267	for (i = 0; i < clwnum && *args; reply = *args++, i++)
268	    setsparam(reply, ztrdup(clwords[i]));
269
270	if (i < clwnum) {
271	    int j, len;
272
273	    for (j = i, len = 0; j < clwnum; len += strlen(clwords[j++]));
274	    bptr = buf = zalloc(len + j - i);
275	    while (i < clwnum) {
276		strucpy(&bptr, clwords[i++]);
277		*bptr++ = ' ';
278	    }
279	    bptr[-1] = '\0';
280	} else
281	    buf = ztrdup("");
282	setsparam(reply, buf);
283    }
284    return 0;
285}
286
287/* Copy a list of completion matchers. */
288
289/**/
290static Cmlist
291cpcmlist(Cmlist l)
292{
293    Cmlist r = NULL, *p = &r, n;
294
295    while (l) {
296	*p = n = (Cmlist) zalloc(sizeof(struct cmlist));
297	n->next = NULL;
298	n->matcher = cpcmatcher(l->matcher);
299	n->str = ztrdup(l->str);
300
301	p = &(n->next);
302	l = l->next;
303    }
304    return r;
305}
306
307/* Set the global match specs. */
308
309/**/
310static int
311set_gmatcher(char *name, char **argv)
312{
313    Cmlist l = NULL, *q = &l, n;
314    Cmatcher m;
315
316    while (*argv) {
317	if ((m = parse_cmatcher(name, *argv)) == pcm_err)
318	    return 1;
319	*q = n = (Cmlist) zhalloc(sizeof(struct cmlist));
320	n->next = NULL;
321	n->matcher = m;
322	n->str = *argv++;
323
324	q = &(n->next);
325    }
326    freecmlist(cmatcher);
327    cmatcher = cpcmlist(l);
328
329    return 1;
330}
331
332/* Try to get the global matcher from the given compctl. */
333
334/**/
335static int
336get_gmatcher(char *name, char **argv)
337{
338    if (!strcmp(*argv, "-M")) {
339	char **p = ++argv;
340
341	while (*p) {
342	    if (**p++ == '-')
343		return 0;
344	}
345	if (set_gmatcher(name, argv))
346	    return 2;
347
348	return 1;
349    }
350    return 0;
351}
352
353/* This prints the global matcher definitions. */
354
355/**/
356static void
357print_gmatcher(int ac)
358{
359    Cmlist p;
360
361    if ((p = cmatcher)) {
362	printf((ac ? "compctl -M" : "MATCH"));
363
364	while (p) {
365	    printf(" \'%s\'", p->str);
366
367	    p = p->next;
368	}
369	putchar('\n');
370    }
371}
372
373/* Parse the basic flags for `compctl' */
374
375/**/
376static int
377get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
378{
379    /* Parse the basic flags for completion:
380     * first is a flag that we are not in extended completion,
381     * while hx indicates or (+) completion (need to know for
382     * default and command completion as the initial compctl is special).
383     * cct is a temporary just to hold flags; it never needs freeing.
384     */
385    struct compctl cct;
386    char **argv = *av;
387    int ready = 0, hx = 0;
388
389    /* Handle `compctl + foo ...' specially:  turn it into
390     * a default compctl by removing it from the hash table.
391     */
392    if (first && argv[0][0] == '+' && !argv[0][1] &&
393	!(argv[1] && argv[1][0] == '-' && argv[1][1])) {
394	argv++;
395	if(argv[0] && argv[0][0] == '-')
396	    argv++;
397	*av = argv;
398	if (cl)
399	    return 1;
400	else {
401	    cclist = COMP_REMOVE;
402	    return 0;
403	}
404    }
405
406    memset((void *)&cct, 0, sizeof(cct));
407    cct.mask2 = CC_CCCONT;
408
409    /* Loop through the flags until we have no more:        *
410     * those with arguments are not properly allocated yet, *
411     * we just hang on to the argument that was passed.     */
412    for (; !ready && argv[0] && argv[0][0] == '-' && (argv[0][1] || !first);) {
413	if (!argv[0][1])
414	    *argv = "-+";
415	while (!ready && *++(*argv)) {
416	    if(**argv == Meta)
417		*++*argv ^= 32;
418	    switch (**argv) {
419	    case 'f':
420		cct.mask |= CC_FILES;
421		break;
422	    case 'c':
423		cct.mask |= CC_COMMPATH;
424		break;
425	    case 'm':
426		cct.mask |= CC_EXTCMDS;
427		break;
428	    case 'w':
429		cct.mask |= CC_RESWDS;
430		break;
431	    case 'o':
432		cct.mask |= CC_OPTIONS;
433		break;
434	    case 'v':
435		cct.mask |= CC_VARS;
436		break;
437	    case 'b':
438		cct.mask |= CC_BINDINGS;
439		break;
440	    case 'A':
441		cct.mask |= CC_ARRAYS;
442		break;
443	    case 'I':
444		cct.mask |= CC_INTVARS;
445		break;
446	    case 'F':
447		cct.mask |= CC_SHFUNCS;
448		break;
449	    case 'p':
450		cct.mask |= CC_PARAMS;
451		break;
452	    case 'E':
453		cct.mask |= CC_ENVVARS;
454		break;
455	    case 'j':
456		cct.mask |= CC_JOBS;
457		break;
458	    case 'r':
459		cct.mask |= CC_RUNNING;
460		break;
461	    case 'z':
462		cct.mask |= CC_STOPPED;
463		break;
464	    case 'B':
465		cct.mask |= CC_BUILTINS;
466		break;
467	    case 'a':
468		cct.mask |= CC_ALREG | CC_ALGLOB;
469		break;
470	    case 'R':
471		cct.mask |= CC_ALREG;
472		break;
473	    case 'G':
474		cct.mask |= CC_ALGLOB;
475		break;
476	    case 'u':
477		cct.mask |= CC_USERS;
478		break;
479	    case 'd':
480		cct.mask |= CC_DISCMDS;
481		break;
482	    case 'e':
483		cct.mask |= CC_EXCMDS;
484		break;
485	    case 'N':
486		cct.mask |= CC_SCALARS;
487		break;
488	    case 'O':
489		cct.mask |= CC_READONLYS;
490		break;
491	    case 'Z':
492		cct.mask |= CC_SPECIALS;
493		break;
494	    case 'q':
495		cct.mask |= CC_REMOVE;
496		break;
497	    case 'U':
498		cct.mask |= CC_DELETE;
499		break;
500	    case 'n':
501		cct.mask |= CC_NAMED;
502		break;
503	    case 'Q':
504		cct.mask |= CC_QUOTEFLAG;
505		break;
506	    case '/':
507		cct.mask |= CC_DIRS;
508		break;
509	    case 't':
510		{
511		    char *p;
512
513		    if (cl) {
514			zwarnnam(name, "illegal option -%c", **argv);
515			return 1;
516		    }
517		    if ((*argv)[1]) {
518			p = (*argv) + 1;
519			*argv = "" - 1;
520		    } else if (!argv[1]) {
521			zwarnnam(name, "retry specification expected after -%c",
522				 **argv);
523			return 1;
524		    } else {
525			p = *++argv;
526			*argv = "" - 1;
527		    }
528		    switch (*p) {
529		    case '+':
530			cct.mask2 = CC_XORCONT;
531			break;
532		    case 'n':
533			cct.mask2 = 0;
534			break;
535		    case '-':
536			cct.mask2 = CC_PATCONT;
537			break;
538		    case 'x':
539			cct.mask2 = CC_DEFCONT;
540			break;
541		    default:
542			zwarnnam(name, "invalid retry specification character `%c'",
543				 *p);
544			return 1;
545		    }
546		    if (p[1]) {
547			zwarnnam(name, "too many retry specification characters: `%s'",
548				 p + 1);
549			return 1;
550		    }
551		}
552		break;
553	    case 'k':
554		if ((*argv)[1]) {
555		    cct.keyvar = (*argv) + 1;
556		    *argv = "" - 1;
557		} else if (!argv[1]) {
558		    zwarnnam(name, "variable name expected after -%c", **argv);
559		    return 1;
560		} else {
561		    cct.keyvar = *++argv;
562		    *argv = "" - 1;
563		}
564		break;
565	    case 'K':
566		if ((*argv)[1]) {
567		    cct.func = (*argv) + 1;
568		    *argv = "" - 1;
569		} else if (!argv[1]) {
570		    zwarnnam(name, "function name expected after -%c", **argv);
571		    return 1;
572		} else {
573		    cct.func = *++argv;
574		    *argv = "" - 1;
575		}
576		break;
577	    case 'Y':
578		cct.mask |= CC_EXPANDEXPL;
579		goto expl;
580	    case 'X':
581		cct.mask &= ~CC_EXPANDEXPL;
582	    expl:
583		if ((*argv)[1]) {
584		    cct.explain = (*argv) + 1;
585		    *argv = "" - 1;
586		} else if (!argv[1]) {
587		    zwarnnam(name, "string expected after -%c", **argv);
588		    return 1;
589		} else {
590		    cct.explain = *++argv;
591		    *argv = "" - 1;
592		}
593		break;
594	    case 'y':
595		if ((*argv)[1]) {
596		    cct.ylist = (*argv) + 1;
597		    *argv = "" - 1;
598		} else if (!argv[1]) {
599		    zwarnnam(name, "function/variable expected after -%c",
600			     **argv);
601		} else {
602		    cct.ylist = *++argv;
603		    *argv = "" - 1;
604		}
605		break;
606	    case 'P':
607		if ((*argv)[1]) {
608		    cct.prefix = (*argv) + 1;
609		    *argv = "" - 1;
610		} else if (!argv[1]) {
611		    zwarnnam(name, "string expected after -%c", **argv);
612		    return 1;
613		} else {
614		    cct.prefix = *++argv;
615		    *argv = "" - 1;
616		}
617		break;
618	    case 'S':
619		if ((*argv)[1]) {
620		    cct.suffix = (*argv) + 1;
621		    *argv = "" - 1;
622		} else if (!argv[1]) {
623		    zwarnnam(name, "string expected after -%c", **argv);
624		    return 1;
625		} else {
626		    cct.suffix = *++argv;
627		    *argv = "" - 1;
628		}
629		break;
630	    case 'g':
631		if ((*argv)[1]) {
632		    cct.glob = (*argv) + 1;
633		    *argv = "" - 1;
634		} else if (!argv[1]) {
635		    zwarnnam(name, "glob pattern expected after -%c", **argv);
636		    return 1;
637		} else {
638		    cct.glob = *++argv;
639		    *argv = "" - 1;
640		}
641		break;
642	    case 's':
643		if ((*argv)[1]) {
644		    cct.str = (*argv) + 1;
645		    *argv = "" - 1;
646		} else if (!argv[1]) {
647		    zwarnnam(name, "command string expected after -%c",
648			     **argv);
649		    return 1;
650		} else {
651		    cct.str = *++argv;
652		    *argv = "" - 1;
653		}
654		break;
655	    case 'l':
656		if (cl) {
657		    zwarnnam(name, "illegal option -%c", **argv);
658		    return 1;
659		} else if ((*argv)[1]) {
660		    cct.subcmd = (*argv) + 1;
661		    *argv = "" - 1;
662		} else if (!argv[1]) {
663		    zwarnnam(name, "command name expected after -%c", **argv);
664		    return 1;
665		} else {
666		    cct.subcmd = *++argv;
667		    *argv = "" - 1;
668		}
669		break;
670	    case 'h':
671		if (cl) {
672		    zwarnnam(name, "illegal option -%c", **argv);
673		    return 1;
674		} else if ((*argv)[1]) {
675		    cct.substr = (*argv) + 1;
676		    *argv = "" - 1;
677		} else if (!argv[1]) {
678		    zwarnnam(name, "command name expected after -%c", **argv);
679		    return 1;
680		} else {
681		    cct.substr = *++argv;
682		    *argv = "" - 1;
683		}
684		break;
685	    case 'W':
686		if ((*argv)[1]) {
687		    cct.withd = (*argv) + 1;
688		    *argv = "" - 1;
689		} else if (!argv[1]) {
690		    zwarnnam(name, "path expected after -%c", **argv);
691		    return 1;
692		} else {
693		    cct.withd = *++argv;
694		    *argv = "" - 1;
695		}
696		break;
697	    case 'J':
698		if ((*argv)[1]) {
699		    cct.gname = (*argv) + 1;
700		    *argv = "" - 1;
701		} else if (!argv[1]) {
702		    zwarnnam(name, "group name expected after -%c", **argv);
703		    return 1;
704		} else {
705		    cct.gname = *++argv;
706		    *argv = "" - 1;
707		}
708		break;
709	    case 'V':
710		if ((*argv)[1]) {
711		    cct.gname = (*argv) + 1;
712		    *argv = "" - 1;
713		} else if (!argv[1]) {
714		    zwarnnam(name, "group name expected after -%c", **argv);
715		    return 1;
716		} else {
717		    cct.gname = *++argv;
718		    *argv = "" - 1;
719		}
720		cct.mask2 |= CC_NOSORT;
721		break;
722	    case '1':
723		cct.mask2 |= CC_UNIQALL;
724		cct.mask2 &= ~CC_UNIQCON;
725		break;
726	    case '2':
727		cct.mask2 |= CC_UNIQCON;
728		cct.mask2 &= ~CC_UNIQALL;
729		break;
730	    case 'M':
731		if (cclist & COMP_LIST) {
732		    cclist |= COMP_LISTMATCH;
733		} else if ((*argv)[1]) {
734		    if ((cct.matcher =
735			 parse_cmatcher(name, (cct.mstr = (*argv) + 1))) ==
736			pcm_err) {
737			cct.matcher = NULL;
738			cct.mstr = NULL;
739			return 1;
740		    }
741		    *argv = "" - 1;
742		} else if (!argv[1]) {
743		    zwarnnam(name, "matching specification expected after -%c",
744			     **argv);
745		    return 1;
746		} else {
747		    if ((cct.matcher =
748			 parse_cmatcher(name, (cct.mstr = *++argv))) ==
749			pcm_err) {
750			cct.matcher = NULL;
751			cct.mstr = NULL;
752			return 1;
753		    }
754		    *argv = "" - 1;
755		}
756		break;
757	    case 'H':
758		if ((*argv)[1])
759		    cct.hnum = atoi((*argv) + 1);
760		else if (argv[1])
761		    cct.hnum = atoi(*++argv);
762		else {
763		    zwarnnam(name, "number expected after -%c", **argv);
764		    return 1;
765		}
766		if (!argv[1]) {
767		    zwarnnam(name, "missing pattern after -%c", **argv);
768		    return 1;
769		}
770		cct.hpat = *++argv;
771		if (cct.hnum < 1)
772		    cct.hnum = 0;
773		if (*cct.hpat == '*' && !cct.hpat[1])
774		    cct.hpat = "";
775		*argv = "" - 1;
776		break;
777	    case 'C':
778		if (cl) {
779		    zwarnnam(name, "illegal option -%c", **argv);
780		    return 1;
781		}
782		if (first && !hx) {
783		    cclist |= COMP_COMMAND;
784		} else {
785		    zwarnnam(name, "misplaced command completion (-C) flag");
786		    return 1;
787		}
788		break;
789	    case 'D':
790		if (cl) {
791		    zwarnnam(name, "illegal option -%c", **argv);
792		    return 1;
793		}
794		if (first && !hx) {
795		    isdef = 1;
796		    cclist |= COMP_DEFAULT;
797		} else {
798		    zwarnnam(name, "misplaced default completion (-D) flag");
799		    return 1;
800		}
801		break;
802 	    case 'T':
803		if (cl) {
804		    zwarnnam(name, "illegal option -%c", **argv);
805		    return 1;
806		}
807		if (first && !hx) {
808 		    cclist |= COMP_FIRST;
809 		} else {
810 		    zwarnnam(name, "misplaced first completion (-T) flag");
811 		    return 1;
812 		}
813 		break;
814	    case 'L':
815		if (cl) {
816		    zwarnnam(name, "illegal option -%c", **argv);
817		    return 1;
818		}
819		if (!first || hx) {
820		    zwarnnam(name, "illegal use of -L flag");
821		    return 1;
822		}
823		cclist |= COMP_LIST;
824		break;
825	    case 'x':
826		if (cl) {
827		    zwarnnam(name, "extended completion not allowed");
828		    return 1;
829		}
830		if (!argv[1]) {
831		    zwarnnam(name, "condition expected after -%c", **argv);
832		    return 1;
833		}
834		if (first) {
835		    argv++;
836		    if (get_xcompctl(name, &argv, &cct, isdef)) {
837			if (cct.ext)
838			    freecompctl(cct.ext);
839			return 1;
840		    }
841		    ready = 2;
842		} else {
843		    zwarnnam(name, "recursive extended completion not allowed");
844		    return 1;
845		}
846		break;
847	    default:
848		if (!first && (**argv == '-' || **argv == '+') && !argv[0][1])
849		    (*argv)--, argv--, ready = 1;
850		else {
851		    zwarnnam(name, "bad option: -%c", **argv);
852		    return 1;
853		}
854	    }
855	}
856
857	if (*++argv && (!ready || ready == 2) &&
858	    **argv == '+' && !argv[0][1]) {
859	    if (cl) {
860		zwarnnam(name, "xor'ed completion illegal");
861		return 1;
862	    }
863	    /* There's an alternative (+) completion:  assign
864	     * what we have so far before moving on to that.
865	     */
866	    if (cc_assign(name, &cc, &cct, first && !hx))
867		return 1;
868
869	    hx = 1;
870	    ready = 0;
871
872	    if (!*++argv || **argv != '-' ||
873		(**argv == '-' && (!argv[0][1] ||
874				   (argv[0][1] == '-' && !argv[0][2])))) {
875		/* No argument to +, which means do default completion */
876		if (isdef)
877		    zwarnnam(name,
878			    "recursive xor'd default completions not allowed");
879		else
880		    cc->xor = &cc_default;
881	    } else {
882		/* more flags follow:  prepare to loop again */
883		cc->xor = (Compctl) zshcalloc(sizeof(*cc));
884		cc = cc->xor;
885		memset((void *)&cct, 0, sizeof(cct));
886		cct.mask2 = CC_CCCONT;
887	    }
888	}
889    }
890    if (!ready && *argv && **argv == '-')
891	argv++;
892
893    if (! (cct.mask & (CC_EXCMDS | CC_DISCMDS)))
894	cct.mask |= CC_EXCMDS;
895
896    /* assign the last set of flags we parsed */
897    if (cc_assign(name, &cc, &cct, first && !hx))
898	return 1;
899
900    *av = argv;
901
902    return 0;
903}
904
905/* Handle the -x ... -- part of compctl. */
906
907/**/
908static int
909get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
910{
911    char **argv = *av, *t, *tt, sav;
912    int n, l = 0, ready = 0;
913    Compcond m, c, o;
914    Compctl *next = &(cc->ext);
915
916    while (!ready) {
917	/* o keeps track of or's, m remembers the starting condition,
918	 * c is the current condition being parsed
919	 */
920	o = m = c = (Compcond) zshcalloc(sizeof(*c));
921	/* Loop over each condition:  something like 's[...][...], p[...]' */
922	for (t = *argv; *t;) {
923	    while (*t == ' ')
924		t++;
925	    /* First get the condition code */
926	    switch (*t) {
927	    case 'q':
928		c->type = CCT_QUOTE;
929		break;
930	    case 's':
931		c->type = CCT_CURSUF;
932		break;
933	    case 'S':
934		c->type = CCT_CURPRE;
935		break;
936	    case 'p':
937		c->type = CCT_POS;
938		break;
939	    case 'c':
940		c->type = CCT_CURSTR;
941		break;
942	    case 'C':
943		c->type = CCT_CURPAT;
944		break;
945	    case 'w':
946		c->type = CCT_WORDSTR;
947		break;
948	    case 'W':
949		c->type = CCT_WORDPAT;
950		break;
951	    case 'n':
952		c->type = CCT_CURSUB;
953		break;
954	    case 'N':
955		c->type = CCT_CURSUBC;
956		break;
957	    case 'm':
958		c->type = CCT_NUMWORDS;
959		break;
960	    case 'r':
961		c->type = CCT_RANGESTR;
962		break;
963	    case 'R':
964		c->type = CCT_RANGEPAT;
965		break;
966	    default:
967		t[1] = '\0';
968		zwarnnam(name, "unknown condition code: %s", t);
969		zfree(m, sizeof(struct compcond));
970
971		return 1;
972	    }
973	    /* Now get the arguments in square brackets */
974	    if (t[1] != '[') {
975		t[1] = '\0';
976		zwarnnam(name, "expected condition after condition code: %s", t);
977		zfree(m, sizeof(struct compcond));
978
979		return 1;
980	    }
981	    t++;
982	    /* First count how many or'd arguments there are,
983	     * marking the active ]'s and ,'s with unprintable characters.
984	     */
985	    for (n = 0, tt = t; *tt == '['; n++) {
986		for (l = 1, tt++; *tt && l; tt++)
987		    if (*tt == '\\' && tt[1])
988			tt++;
989		    else if (*tt == '[')
990			l++;
991		    else if (*tt == ']')
992			l--;
993		    else if (l == 1 && *tt == ',')
994			*tt = '\201';
995		if (tt[-1] == ']')
996		    tt[-1] = '\200';
997	    }
998
999	    if (l) {
1000		t[1] = '\0';
1001		zwarnnam(name, "error after condition code: %s", t);
1002		zfree(m, sizeof(struct compcond));
1003
1004		return 1;
1005	    }
1006	    c->n = n;
1007
1008	    /* Allocate space for all the arguments of the conditions */
1009	    if (c->type == CCT_POS ||
1010		c->type == CCT_NUMWORDS) {
1011		c->u.r.a = (int *)zshcalloc(n * sizeof(int));
1012		c->u.r.b = (int *)zshcalloc(n * sizeof(int));
1013	    } else if (c->type == CCT_CURSUF ||
1014		       c->type == CCT_CURPRE ||
1015		       c->type == CCT_QUOTE)
1016		c->u.s.s = (char **)zshcalloc(n * sizeof(char *));
1017
1018	    else if (c->type == CCT_RANGESTR ||
1019		     c->type == CCT_RANGEPAT) {
1020		c->u.l.a = (char **)zshcalloc(n * sizeof(char *));
1021		c->u.l.b = (char **)zshcalloc(n * sizeof(char *));
1022	    } else {
1023		c->u.s.p = (int *)zshcalloc(n * sizeof(int));
1024		c->u.s.s = (char **)zshcalloc(n * sizeof(char *));
1025	    }
1026	    /* Now loop over the actual arguments */
1027	    for (l = 0; *t == '['; l++, t++) {
1028		for (t++; *t && *t == ' '; t++);
1029		tt = t;
1030		if (c->type == CCT_POS ||
1031		    c->type == CCT_NUMWORDS) {
1032		    /* p[...] or m[...]:  one or two numbers expected */
1033		    for (; *t && *t != '\201' && *t != '\200'; t++);
1034		    if (!(sav = *t)) {
1035			zwarnnam(name, "error in condition");
1036			freecompcond(m);
1037			return 1;
1038		    }
1039		    *t = '\0';
1040		    c->u.r.a[l] = atoi(tt);
1041		    /* Second argument is optional:  see if it's there */
1042		    if (sav == '\200')
1043			/* no:  copy first argument */
1044			c->u.r.b[l] = c->u.r.a[l];
1045		    else {
1046			tt = ++t;
1047			for (; *t && *t != '\200'; t++);
1048			if (!*t) {
1049			    zwarnnam(name, "error in condition");
1050			    freecompcond(m);
1051			    return 1;
1052			}
1053			*t = '\0';
1054			c->u.r.b[l] = atoi(tt);
1055		    }
1056		} else if (c->type == CCT_CURSUF ||
1057			   c->type == CCT_CURPRE ||
1058			   c->type == CCT_QUOTE) {
1059		    /* -s[..] or -S[..]:  single string expected */
1060		    for (; *t && *t != '\200'; t++)
1061			if (*t == '\201')
1062			    *t = ',';
1063		    if (!*t) {
1064			zwarnnam(name, "error in condition");
1065			freecompcond(m);
1066			return 1;
1067		    }
1068		    *t = '\0';
1069		    c->u.s.s[l] = ztrdup(tt);
1070		} else if (c->type == CCT_RANGESTR ||
1071			   c->type == CCT_RANGEPAT) {
1072		    int hc;
1073
1074		    /* -r[..,..] or -R[..,..]:  two strings expected */
1075		    for (; *t && *t != '\201' && *t != '\200'; t++);
1076		    if (!*t) {
1077			zwarnnam(name, "error in condition");
1078			freecompcond(m);
1079			return 1;
1080		    }
1081		    hc = (*t == '\201');
1082		    *t = '\0';
1083		    c->u.l.a[l] = ztrdup(tt);
1084		    if (hc) {
1085			tt = ++t;
1086			/* any more commas are text, not active */
1087			for (; *t && *t != '\200'; t++)
1088			    if (*t == '\201')
1089				*t = ',';
1090			if (!*t) {
1091			    zwarnnam(name, "error in condition");
1092			    freecompcond(m);
1093			    return 1;
1094			}
1095			*t = '\0';
1096			c->u.l.b[l] = ztrdup(tt);
1097		    }
1098		    else
1099			c->u.l.b[l] = NULL;
1100		} else {
1101		    /* remaining patterns are number followed by string */
1102		    for (; *t && *t != '\200' && *t != '\201'; t++);
1103		    if (!*t || *t == '\200') {
1104			zwarnnam(name, "error in condition");
1105			freecompcond(m);
1106			return 1;
1107		    }
1108		    *t = '\0';
1109		    c->u.s.p[l] = atoi(tt);
1110		    tt = ++t;
1111		    for (; *t && *t != '\200'; t++)
1112			if (*t == '\201')
1113			    *t = ',';
1114		    if (!*t) {
1115			zwarnnam(name, "error in condition");
1116			freecompcond(m);
1117			return 1;
1118		    }
1119		    *t = '\0';
1120		    c->u.s.s[l] = ztrdup(tt);
1121		}
1122	    }
1123	    while (*t == ' ')
1124		t++;
1125	    if (*t == ',') {
1126		/* Another condition to `or' */
1127		o->or = c = (Compcond) zshcalloc(sizeof(*c));
1128		o = c;
1129		t++;
1130	    } else if (*t) {
1131		/* Another condition to `and' */
1132		c->and = (Compcond) zshcalloc(sizeof(*c));
1133		c = c->and;
1134	    }
1135	}
1136	/* Assign condition to current compctl */
1137	*next = (Compctl) zshcalloc(sizeof(*cc));
1138	(*next)->cond = m;
1139	argv++;
1140	/* End of the condition; get the flags that go with it. */
1141	if (get_compctl(name, &argv, *next, 0, isdef, 0))
1142	    return 1;
1143 	if ((!argv || !*argv) && (cclist & COMP_SPECIAL))
1144 	    /* default, first, or command completion finished */
1145	    ready = 1;
1146	else {
1147	    /* see if we are looking for more conditions or are
1148	     * ready to return (ready = 1)
1149	     */
1150	    if (!argv || !*argv || **argv != '-' ||
1151		((!argv[0][1] || argv[0][1] == '+') && !argv[1])) {
1152		zwarnnam(name, "missing command names");
1153		return 1;
1154	    }
1155	    if (!strcmp(*argv, "--"))
1156		ready = 1;
1157	    else if (!strcmp(*argv, "-+") && argv[1] &&
1158		     !strcmp(argv[1], "--")) {
1159		ready = 1;
1160		argv++;
1161	    }
1162	    argv++;
1163	    /* prepare to put the next lot of conditions on the end */
1164	    next = &((*next)->next);
1165	}
1166    }
1167    /* save position at end of parsing */
1168    *av = argv - 1;
1169    return 0;
1170}
1171
1172/**/
1173static int
1174cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass)
1175{
1176    /* Copy over the details from the values in cct to those in *ccptr */
1177    Compctl cc;
1178
1179    /* Handle assignment of new default or command completion */
1180    if (reass && !(cclist & COMP_LIST)) {
1181	/* if not listing */
1182	if (cclist == (COMP_COMMAND|COMP_DEFAULT)
1183	    || cclist == (COMP_COMMAND|COMP_FIRST)
1184	    || cclist == (COMP_DEFAULT|COMP_FIRST)
1185	    || cclist == COMP_SPECIAL) {
1186 	    zwarnnam(name, "can't set -D, -T, and -C simultaneously");
1187	    /* ... because the following code wouldn't work. */
1188	    return 1;
1189	}
1190	if (cclist & COMP_COMMAND) {
1191	    /* command */
1192	    *ccptr = &cc_compos;
1193	    cc_reassign(*ccptr);
1194	} else if (cclist & COMP_DEFAULT) {
1195	    /* default */
1196	    *ccptr = &cc_default;
1197	    cc_reassign(*ccptr);
1198 	} else if (cclist & COMP_FIRST) {
1199 	    /* first */
1200 	    *ccptr = &cc_first;
1201 	    cc_reassign(*ccptr);
1202	}
1203    }
1204
1205    /* Free the old compctl */
1206    cc = *ccptr;
1207    zsfree(cc->keyvar);
1208    zsfree(cc->glob);
1209    zsfree(cc->str);
1210    zsfree(cc->func);
1211    zsfree(cc->explain);
1212    zsfree(cc->ylist);
1213    zsfree(cc->prefix);
1214    zsfree(cc->suffix);
1215    zsfree(cc->subcmd);
1216    zsfree(cc->substr);
1217    zsfree(cc->withd);
1218    zsfree(cc->hpat);
1219    zsfree(cc->gname);
1220    zsfree(cc->mstr);
1221    freecmatcher(cc->matcher);
1222
1223    /* and copy over the new stuff, (permanently) allocating
1224     * space for strings.
1225     */
1226    cc->mask = cct->mask;
1227    cc->mask2 = cct->mask2;
1228    cc->keyvar = ztrdup(cct->keyvar);
1229    cc->glob = ztrdup(cct->glob);
1230    cc->str = ztrdup(cct->str);
1231    cc->func = ztrdup(cct->func);
1232    cc->explain = ztrdup(cct->explain);
1233    cc->ylist = ztrdup(cct->ylist);
1234    cc->prefix = ztrdup(cct->prefix);
1235    cc->suffix = ztrdup(cct->suffix);
1236    cc->subcmd = ztrdup(cct->subcmd);
1237    cc->substr = ztrdup(cct->substr);
1238    cc->withd = ztrdup(cct->withd);
1239    cc->gname = ztrdup(cct->gname);
1240    cc->hpat = ztrdup(cct->hpat);
1241    cc->hnum = cct->hnum;
1242    cc->matcher = cpcmatcher(cct->matcher);
1243    cc->mstr = ztrdup(cct->mstr);
1244
1245    /* careful with extended completion:  it's already allocated */
1246    cc->ext = cct->ext;
1247
1248    return 0;
1249}
1250
1251/**/
1252static void
1253cc_reassign(Compctl cc)
1254{
1255    /* Free up a new default or command completion:
1256     * this is a hack to free up the parts which should be deleted,
1257     * without removing the basic variable which is statically allocated
1258     */
1259    Compctl c2;
1260
1261    c2 = (Compctl) zshcalloc(sizeof *cc);
1262    c2->xor = cc->xor;
1263    c2->ext = cc->ext;
1264    c2->refc = 1;
1265
1266    freecompctl(c2);
1267
1268    cc->ext = cc->xor = NULL;
1269}
1270
1271/* Check if the given string is a pattern. If so, return one and tokenize *
1272 * it. If not, we just remove the backslashes. */
1273
1274static int
1275compctl_name_pat(char **p)
1276{
1277    char *s = *p;
1278
1279    tokenize(s = dupstring(s));
1280    remnulargs(s);
1281
1282    if (haswilds(s)) {
1283	*p = s;
1284	return 1;
1285    } else
1286	*p = rembslash(*p);
1287
1288    return 0;
1289}
1290
1291/* Delete the pattern compctl with the given name. */
1292
1293static void
1294delpatcomp(char *n)
1295{
1296    Patcomp p, q;
1297
1298    for (q = 0, p = patcomps; p; q = p, p = p->next) {
1299	if (!strcmp(n, p->pat)) {
1300	    if (q)
1301		q->next = p->next;
1302	    else
1303		patcomps = p->next;
1304	    zsfree(p->pat);
1305	    freecompctl(p->cc);
1306	    free(p);
1307
1308	    break;
1309	}
1310    }
1311}
1312
1313/**/
1314static void
1315compctl_process_cc(char **s, Compctl cc)
1316{
1317    Compctlp ccp;
1318    char *n;
1319
1320    if (cclist & COMP_REMOVE) {
1321	/* Delete entries for the commands listed */
1322	for (; *s; s++) {
1323	    n = *s;
1324	    if (compctl_name_pat(&n))
1325		delpatcomp(n);
1326	    else if ((ccp = (Compctlp) compctltab->removenode(compctltab, n)))
1327		compctltab->freenode(&ccp->node);
1328	}
1329    } else {
1330	/* Add the compctl just read to the hash table */
1331
1332	cc->refc = 0;
1333	for (; *s; s++) {
1334	    n = *s;
1335
1336	    cc->refc++;
1337	    if (compctl_name_pat(&n)) {
1338		Patcomp pc;
1339
1340		delpatcomp(n);
1341		pc = zalloc(sizeof *pc);
1342		pc->pat = ztrdup(n);
1343		pc->cc = cc;
1344		pc->next = patcomps;
1345		patcomps = pc;
1346	    } else {
1347		ccp = (Compctlp) zalloc(sizeof *ccp);
1348		ccp->cc = cc;
1349		compctltab->addnode(compctltab, ztrdup(n), ccp);
1350	    }
1351	}
1352    }
1353}
1354
1355/* Print a `compctl' */
1356
1357/**/
1358static void
1359printcompctl(char *s, Compctl cc, int printflags, int ispat)
1360{
1361    Compctl cc2;
1362    char *css = "fcqovbAIFpEjrzBRGudeNOZUnQmw/";
1363    char *mss = " pcCwWsSnNmrRq";
1364    unsigned long t = 0x7fffffff;
1365    unsigned long flags = cc->mask, flags2 = cc->mask2;
1366    unsigned long oldshowmask;
1367
1368    /* Printflags is used outside the standard compctl commands*/
1369    if (printflags & PRINT_LIST)
1370	cclist |= COMP_LIST;
1371    else if (printflags & PRINT_TYPE)
1372	cclist &= ~COMP_LIST;
1373
1374    if ((flags & CC_EXCMDS) && !(flags & CC_DISCMDS))
1375	flags &= ~CC_EXCMDS;
1376
1377    /* If showmask is non-zero, then print only those *
1378     * commands with that flag set.                   */
1379    if (showmask && !(flags & showmask))
1380	return;
1381
1382    /* Temporarily clear showmask in case we make *
1383     * recursive calls to printcompctl.           */
1384    oldshowmask = showmask;
1385    showmask = 0;
1386
1387    /* print either command name or start of compctl command itself */
1388    if (s) {
1389	if (cclist & COMP_LIST) {
1390	    printf("compctl");
1391	    if (cc == &cc_compos)
1392		printf(" -C");
1393	    if (cc == &cc_default)
1394		printf(" -D");
1395	    if (cc == &cc_first)
1396		printf(" -T");
1397	} else if (ispat) {
1398	    char *p = dupstring(s);
1399
1400	    untokenize(p);
1401	    quotedzputs(p, stdout);
1402	} else
1403	    quotedzputs(quotestring(s, NULL, QT_BACKSLASH), stdout);
1404    }
1405
1406    /* loop through flags w/o args that are set, printing them if so */
1407    if ((flags & t) || (flags2 & (CC_UNIQALL | CC_UNIQCON))) {
1408	printf(" -");
1409	if ((flags & (CC_ALREG | CC_ALGLOB)) == (CC_ALREG | CC_ALGLOB))
1410	    putchar('a'), flags &= ~(CC_ALREG | CC_ALGLOB);
1411	while (*css) {
1412	    if (flags & t & 1)
1413		putchar(*css);
1414	    css++;
1415	    flags >>= 1;
1416	    t >>= 1;
1417	}
1418	if (flags2 & CC_UNIQALL)
1419	    putchar('1');
1420	else if (flags2 & CC_UNIQCON)
1421	    putchar('2');
1422    }
1423    if (flags2 & (CC_XORCONT | CC_PATCONT | CC_DEFCONT)) {
1424	printf(" -t");
1425	if (flags2 & CC_XORCONT)
1426	    putchar('+');
1427	if (flags2 & CC_PATCONT)
1428	    putchar('-');
1429	if (flags2 & CC_DEFCONT)
1430	    putchar('x');
1431    } else if (!(flags2 & CC_CCCONT))
1432	printf(" -tn");
1433    /* now flags with arguments */
1434    printif(cc->mstr, 'M');
1435    if (flags2 & CC_NOSORT)
1436	printif(cc->gname, 'V');
1437    else
1438	printif(cc->gname, 'J');
1439    printif(cc->keyvar, 'k');
1440    printif(cc->func, 'K');
1441    printif(cc->explain, (cc->mask & CC_EXPANDEXPL) ? 'Y' : 'X');
1442    printif(cc->ylist, 'y');
1443    printif(cc->prefix, 'P');
1444    printif(cc->suffix, 'S');
1445    printif(cc->glob, 'g');
1446    printif(cc->str, 's');
1447    printif(cc->subcmd, 'l');
1448    printif(cc->substr, 'h');
1449    printif(cc->withd, 'W');
1450    if (cc->hpat) {
1451	printf(" -H %d ", cc->hnum);
1452	quotedzputs(cc->hpat, stdout);
1453    }
1454
1455    /* now the -x ... -- extended completion part */
1456    if (cc->ext) {
1457	Compcond c, o;
1458	int i;
1459
1460	cc2 = cc->ext;
1461	printf(" -x");
1462
1463	while (cc2) {
1464	    /* loop over conditions */
1465	    c = cc2->cond;
1466
1467	    printf(" '");
1468	    for (c = cc2->cond; c;) {
1469		/* loop over or's */
1470		o = c->or;
1471		while (c) {
1472		    /* loop over and's */
1473		    putchar(mss[c->type]);
1474
1475		    for (i = 0; i < c->n; i++) {
1476			/* for all [...]'s of a given condition */
1477			putchar('[');
1478			switch (c->type) {
1479			case CCT_POS:
1480			case CCT_NUMWORDS:
1481			    printf("%d,%d", c->u.r.a[i], c->u.r.b[i]);
1482			    break;
1483			case CCT_CURSUF:
1484			case CCT_CURPRE:
1485			case CCT_QUOTE:
1486			    printqt(c->u.s.s[i]);
1487			    break;
1488			case CCT_RANGESTR:
1489			case CCT_RANGEPAT:
1490			    printqt(c->u.l.a[i]);
1491			    putchar(',');
1492			    printqt(c->u.l.b[i]);
1493			    break;
1494			default:
1495			    printf("%d,", c->u.s.p[i]);
1496			    printqt(c->u.s.s[i]);
1497			}
1498			putchar(']');
1499		    }
1500		    if ((c = c->and))
1501			putchar(' ');
1502		}
1503		if ((c = o))
1504		    printf(" , ");
1505	    }
1506	    putchar('\'');
1507	    c = cc2->cond;
1508	    cc2->cond = NULL;
1509	    /* now print the flags for the current condition */
1510	    printcompctl(NULL, cc2, 0, 0);
1511	    cc2->cond = c;
1512	    if ((cc2 = (Compctl) (cc2->next)))
1513		printf(" -");
1514	}
1515	if (cclist & COMP_LIST)
1516	    printf(" --");
1517    }
1518    if (cc && cc->xor) {
1519	/* print xor'd (+) completions */
1520	printf(" +");
1521	if (cc->xor != &cc_default)
1522	    printcompctl(NULL, cc->xor, 0, 0);
1523    }
1524    if (s) {
1525	if ((cclist & COMP_LIST) && (cc != &cc_compos)
1526	    && (cc != &cc_default) && (cc != &cc_first)) {
1527	    if(s[0] == '-' || s[0] == '+')
1528		printf(" -");
1529	    putchar(' ');
1530	    if (ispat) {
1531		char *p = dupstring(s);
1532
1533		untokenize(p);
1534		quotedzputs(p, stdout);
1535	    } else {
1536		char *p = dupstring(s);
1537
1538		untokenize(p);
1539		quotedzputs(quotestring(p, NULL, QT_BACKSLASH), stdout);
1540	    }
1541	}
1542	putchar('\n');
1543    }
1544
1545    showmask = oldshowmask;
1546}
1547
1548/**/
1549static void
1550printcompctlp(HashNode hn, int printflags)
1551{
1552    Compctlp ccp = (Compctlp) hn;
1553
1554    /* Function needed for use by scanhashtable() */
1555    printcompctl(ccp->node.nam, ccp->cc, printflags, 0);
1556}
1557
1558/* Main entry point for the `compctl' builtin */
1559
1560/**/
1561static int
1562bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
1563{
1564    Compctl cc = NULL;
1565    int ret = 0;
1566
1567    /* clear static flags */
1568    cclist = 0;
1569    showmask = 0;
1570
1571    /* Parse all the arguments */
1572    if (*argv) {
1573	/* Let's see if this is a global matcher definition. */
1574	if ((ret = get_gmatcher(name, argv)))
1575	    return ret - 1;
1576
1577	cc = (Compctl) zshcalloc(sizeof(*cc));
1578	if (get_compctl(name, &argv, cc, 1, 0, 0)) {
1579	    freecompctl(cc);
1580	    return 1;
1581	}
1582
1583	/* remember flags for printing */
1584	showmask = cc->mask;
1585	if ((showmask & CC_EXCMDS) && !(showmask & CC_DISCMDS))
1586	    showmask &= ~CC_EXCMDS;
1587
1588	/* if no command arguments or just listing, we don't want cc */
1589	if (!*argv || (cclist & COMP_LIST))
1590	    freecompctl(cc);
1591    }
1592
1593    /* If no commands and no -C, -T, or -D, print all the compctl's *
1594     * If some flags (other than -C, -T, or -D) were given, then    *
1595     * only print compctl containing those flags.                   */
1596    if (!*argv && !(cclist & (COMP_SPECIAL|COMP_LISTMATCH))) {
1597	Patcomp pc;
1598
1599	for (pc = patcomps; pc; pc = pc->next)
1600	    printcompctl(pc->pat, pc->cc, 0, 1);
1601
1602	scanhashtable(compctltab, 1, 0, 0, compctltab->printnode, 0);
1603	printcompctl((cclist & COMP_LIST) ? "" : "COMMAND", &cc_compos, 0, 0);
1604	printcompctl((cclist & COMP_LIST) ? "" : "DEFAULT", &cc_default, 0, 0);
1605 	printcompctl((cclist & COMP_LIST) ? "" : "FIRST", &cc_first, 0, 0);
1606	print_gmatcher((cclist & COMP_LIST));
1607	return ret;
1608    }
1609
1610    /* If we're listing and we've made it to here, then there are arguments *
1611     * or a COMP_SPECIAL flag (-D, -C, -T), so print only those.            */
1612    if (cclist & COMP_LIST) {
1613	HashNode hn;
1614	char **ptr, *n;
1615
1616	showmask = 0;
1617	for (ptr = argv; *ptr; ptr++) {
1618	    n = *ptr;
1619	    if (compctl_name_pat(&n)) {
1620		Patcomp pc;
1621
1622		for (pc = patcomps; pc; pc = pc->next)
1623		    if (!strcmp(n, pc->pat)) {
1624			printcompctl(pc->pat, pc->cc, 0, 1);
1625			n = NULL;
1626			break;
1627		    }
1628	    } else if ((hn = compctltab->getnode(compctltab, n))) {
1629		compctltab->printnode(hn, 0);
1630		n = NULL;
1631	    }
1632	    if (n) {
1633		zwarnnam(name, "no compctl defined for %s", n);
1634		ret = 1;
1635	    }
1636	}
1637	if (cclist & COMP_COMMAND)
1638	    printcompctl("", &cc_compos, 0, 0);
1639	if (cclist & COMP_DEFAULT)
1640	    printcompctl("", &cc_default, 0, 0);
1641	if (cclist & COMP_FIRST)
1642	    printcompctl("", &cc_first, 0, 0);
1643	if (cclist & COMP_LISTMATCH)
1644	    print_gmatcher(COMP_LIST);
1645	return ret;
1646    }
1647
1648    /* Assign the compctl to the commands given */
1649    if (*argv) {
1650	if(cclist & COMP_SPECIAL)
1651	    /* Ideally we'd handle this properly, setting both the *
1652	     * special and normal completions.  For the moment,    *
1653	     * this is better than silently failing.               */
1654	    zwarnnam(name, "extraneous commands ignored");
1655	else
1656	    compctl_process_cc(argv, cc);
1657    }
1658
1659    return ret;
1660}
1661
1662/* Flags for makecomplist*(). Things not to do. */
1663
1664#define CFN_FIRST   1
1665#define CFN_DEFAULT 2
1666
1667static int
1668bin_compcall(char *name, UNUSED(char **argv), Options ops, UNUSED(int func))
1669{
1670    if (incompfunc != 1) {
1671	zwarnnam(name, "can only be called from completion function");
1672	return 1;
1673    }
1674    return makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
1675			   (OPT_ISSET(ops,'D') ? 0 : CFN_DEFAULT));
1676}
1677
1678/*
1679 * Functions to generate matches.
1680 */
1681
1682/* A pointer to the compctl we are using. */
1683
1684static Compctl curcc;
1685
1686/* A list of all compctls we have already used. */
1687
1688static LinkList ccused, lastccused;
1689
1690/* A stack of currently used compctls. */
1691
1692static LinkList ccstack;
1693
1694/* The beginning and end of a word range to be used by -l. */
1695
1696static int brange, erange;
1697
1698/* This is used to detect when and what to continue. */
1699
1700static unsigned long ccont;
1701
1702/* Two patterns used when doing glob-completion.  The first one is built *
1703 * from the whole word we are completing and the second one from that    *
1704 * part of the word that was identified as a possible filename.          */
1705
1706static Patprog patcomp, filecomp;
1707
1708/* We store the following prefixes/suffixes:                               *
1709 * lpre/lsuf -- what's on the line                                         *
1710 * rpre/rsuf -- same as lpre/lsuf, but expanded                            *
1711 * ppre/psuf   -- the path prefix/suffix                                   *
1712 * lppre/lpsuf -- the path prefix/suffix, unexpanded                       *
1713 * fpre/fsuf   -- prefix/suffix of the pathname component the cursor is in *
1714 * prpre       -- ppre in expanded form usable for opendir                 *
1715 * qipre, qisuf-- ingnored quoted string                                   *
1716 *                                                                         *
1717 * The integer variables hold the lengths of lpre, lsuf, rpre, rsuf,       *
1718 * fpre, fsuf, lppre, and lpsuf.  noreal is non-zero if we have rpre/rsuf. */
1719
1720static char *lpre, *lsuf;
1721static char *rpre, *rsuf;
1722static char *ppre, *psuf, *lppre, *lpsuf, *prpre;
1723static char *fpre, *fsuf;
1724static char *qfpre, *qfsuf, *qrpre, *qrsuf, *qlpre, *qlsuf;
1725static int lpl, lsl, rpl, rsl, fpl, fsl, lppl, lpsl;
1726static int noreal;
1727
1728/* This is either zero or equal to the special character the word we are *
1729 * trying to complete starts with (e.g. Tilde or Equals).                */
1730
1731static char ic;
1732
1733/* This variable says what we are currently adding to the list of matches. */
1734
1735static int addwhat;
1736
1737/*
1738 * Convenience macro for calling quotestring (formerly bslashquote()
1739 * (formerly quotename())).
1740 * This uses the instring variable exported from zle_tricky.c.
1741 */
1742
1743#define quotename(s, e) \
1744quotestring(s, e, instring == QT_NONE ? QT_BACKSLASH : instring)
1745
1746/* Hook functions */
1747
1748static int
1749ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
1750{
1751    char *s = dat->str;
1752    int incmd = dat->incmd, lst = dat->lst;
1753    struct cmlist ms;
1754    Cmlist m;
1755    char *os = s;
1756    int onm = nmatches, odm = diffmatches, osi = movefd(0);
1757    LinkNode n;
1758
1759    /* We build a copy of the list of matchers to use to make sure that this
1760     * works even if a shell function called from the completion code changes
1761     * the global matchers. */
1762
1763    if ((m = cmatcher)) {
1764	Cmlist mm, *mp = &mm;
1765	int n;
1766
1767	for (n = 0; m; m = m->next, n++) {
1768	    *mp = (Cmlist) zhalloc(sizeof(struct cmlist));
1769	    (*mp)->matcher = m->matcher;
1770	    (*mp)->next = NULL;
1771	    (*mp)->str = dupstring(m->str);
1772	    mp = &((*mp)->next);
1773	    addlinknode(matchers, m->matcher);
1774	    if (m->matcher)
1775		m->matcher->refc++;
1776	}
1777	m = mm;
1778    }
1779
1780    /* Walk through the global matchers. */
1781    for (;;) {
1782	bmatchers = NULL;
1783	if (m) {
1784	    ms.next = NULL;
1785	    ms.matcher = m->matcher;
1786	    mstack = &ms;
1787
1788	    /* Store the matchers used in the bmatchers list which is used
1789	     * when building new parts for the string to insert into the
1790	     * line. */
1791	    add_bmatchers(m->matcher);
1792	} else
1793	    mstack = NULL;
1794
1795	ainfo = (Aminfo) hcalloc(sizeof(struct aminfo));
1796	fainfo = (Aminfo) hcalloc(sizeof(struct aminfo));
1797
1798	freecl = NULL;
1799
1800	if (!validlist)
1801	    lastambig = 0;
1802	amatches = NULL;
1803	mnum = 0;
1804	unambig_mnum = -1;
1805	isuf = NULL;
1806	insmnum = 1;
1807#if 0
1808	/* group-numbers in compstate[insert] */
1809	insgnum = 1;
1810	insgroup = 0;
1811#endif
1812	oldlist = oldins = 0;
1813	begcmgroup("default", 0);
1814	menucmp = menuacc = newmatches = onlyexpl = 0;
1815
1816	ccused = newlinklist();
1817	ccstack = newlinklist();
1818
1819	s = dupstring(os);
1820	makecomplistglobal(s, incmd, lst, 0);
1821	endcmgroup(NULL);
1822
1823	if (amatches && !oldlist) {
1824	    if (lastccused)
1825		freelinklist(lastccused, (FreeFunc) freecompctl);
1826
1827	    lastccused = znewlinklist();
1828	    for (n = firstnode(ccused); n; incnode(n))
1829		zaddlinknode(lastccused, getdata(n));
1830	} else if (ccused)
1831	    for (n = firstnode(ccused); n; incnode(n))
1832		if (((Compctl) getdata(n)) != &cc_dummy)
1833		    freecompctl((Compctl) getdata(n));
1834
1835	if (oldlist) {
1836	    nmatches = onm;
1837	    diffmatches = odm;
1838	    validlist = 1;
1839	    amatches = lastmatches;
1840#ifdef ZSH_HEAP_DEBUG
1841	    if (memory_validate(amatches->heap_id)) {
1842		HEAP_ERROR(amatches->heap_id);
1843	    }
1844#endif
1845	    lmatches = lastlmatches;
1846	    if (pmatches) {
1847		freematches(pmatches, 1);
1848		pmatches = NULL;
1849		hasperm = 0;
1850	    }
1851	    redup(osi, 0);
1852
1853	    dat->lst = 0;
1854	    return 0;
1855	}
1856	if (lastmatches) {
1857	    freematches(lastmatches, 1);
1858	    lastmatches = NULL;
1859	}
1860	permmatches(1);
1861	amatches = pmatches;
1862	lastpermmnum = permmnum;
1863	lastpermgnum = permgnum;
1864
1865	lastmatches = pmatches;
1866	lastlmatches = lmatches;
1867	pmatches = NULL;
1868	hasperm = 0;
1869	hasoldlist = 1;
1870
1871	if (nmatches && !errflag) {
1872	    validlist = 1;
1873
1874	    redup(osi, 0);
1875
1876	    dat->lst = 0;
1877	    return 0;
1878	}
1879	if (!m || !(m = m->next))
1880	    break;
1881
1882	errflag = 0;
1883    }
1884    redup(osi, 0);
1885    dat->lst = 1;
1886    return 0;
1887}
1888
1889static int
1890cccleanuphookfn(UNUSED(Hookdef dummy), UNUSED(void *dat))
1891{
1892    ccused = ccstack = NULL;
1893    return 0;
1894}
1895
1896/* This adds a match to the list of matches.  The string to add is given   *
1897 * in s, the type of match is given in the global variable addwhat and     *
1898 * the parameter t (if not NULL) is a pointer to a hash node which         *
1899 * may be used to give other information to this function.                 *
1900 *                                                                         *
1901 * addwhat contains either one of the special values (negative, see below) *
1902 * or the inclusive OR of some of the CC_* flags used for compctls.        */
1903
1904/**/
1905static void
1906addmatch(char *s, char *t)
1907{
1908    int isfile = 0, isalt = 0, isexact;
1909    char *ms = NULL, *tt;
1910    HashNode hn;
1911    Param pm;
1912    Cline lc = NULL;
1913    Brinfo bp, bpl = brbeg, bsl = brend, bpt, bst;
1914
1915    for (bp = brbeg; bp; bp = bp->next)
1916	bp->curpos = ((addwhat == CC_QUOTEFLAG) ? bp->qpos : bp->pos);
1917    for (bp = brend; bp; bp = bp->next)
1918	bp->curpos = ((addwhat == CC_QUOTEFLAG) ? bp->qpos : bp->pos);
1919
1920    /*
1921     * addwhat: -5 is for files,
1922     *          -6 is for glob expansions,
1923     *          -8 is for executable files (e.g. command paths),
1924     *          -9 is for parameters
1925     *          -7 is for command names (from cmdnamtab)
1926     *          -4 is for a cdable parameter
1927     *          -3 is for executable command names.
1928     *          -2 is for anything unquoted
1929     *          -1 is for other file specifications
1930     *          (things with `~' or `=' at the beginning, ...).
1931     */
1932
1933    /* Just to make the code cleaner */
1934    hn = (HashNode) t;
1935    pm = (Param) t;
1936
1937    if (addwhat == -1 || addwhat == -5 || addwhat == -6 ||
1938	addwhat == CC_FILES || addwhat == -7 || addwhat == -8) {
1939	int ppl = (ppre ? strlen(ppre) : 0), psl = (psuf ? strlen(psuf) : 0);
1940
1941	while (bpl && bpl->curpos < ppl)
1942	    bpl = bpl->next;
1943	while (bsl && bsl->curpos < psl)
1944	    bsl = bsl->next;
1945
1946	if ((addwhat == CC_FILES ||
1947	     addwhat == -5) && !*psuf) {
1948	    /* If this is a filename, do the fignore check. */
1949	    char **pt = fignore;
1950	    int filell, sl = strlen(s);
1951
1952	    for (isalt = 0; !isalt && *pt; pt++)
1953		if ((filell = strlen(*pt)) < sl &&
1954		    !strcmp(*pt, s + sl - filell))
1955		    isalt = 1;
1956	}
1957	ms = ((addwhat == CC_FILES || addwhat == -6 ||
1958	       addwhat == -5 || addwhat == -8) ?
1959	      comp_match(tildequote(qfpre, 1), multiquote(qfsuf, 1),
1960			 s, filecomp, &lc, (ppre && *ppre ? 1 : 2),
1961			 &bpl, ppl ,&bsl, psl, &isexact) :
1962	      comp_match(multiquote(fpre, 1), multiquote(fsuf, 1),
1963			 s, filecomp, &lc, 0,
1964			 &bpl, ppl, &bsl, psl, &isexact));
1965	if (!ms)
1966	    return;
1967
1968	if (addwhat == -7 && !findcmd(s, 0))
1969	    return;
1970	isfile = CMF_FILE;
1971    } else if (addwhat == CC_QUOTEFLAG || addwhat == -2  ||
1972	      (addwhat == -3 && !(hn->flags & DISABLED)) ||
1973	      (addwhat == -4 && (PM_TYPE(pm->node.flags) == PM_SCALAR) &&
1974	       !pm->level && (tt = pm->gsu.s->getfn(pm)) && *tt == '/') ||
1975	      (addwhat == -9 && !(hn->flags & PM_UNSET) && !pm->level) ||
1976	      (addwhat > 0 &&
1977	       ((!(hn->flags & PM_UNSET) &&
1978		 (((addwhat & CC_ARRAYS)    &&  (hn->flags & PM_ARRAY))    ||
1979		  ((addwhat & CC_INTVARS)   &&  (hn->flags & PM_INTEGER))  ||
1980		  ((addwhat & CC_ENVVARS)   &&  (hn->flags & PM_EXPORTED)) ||
1981		  ((addwhat & CC_SCALARS)   &&  (hn->flags & PM_SCALAR))   ||
1982		  ((addwhat & CC_READONLYS) &&  (hn->flags & PM_READONLY)) ||
1983		  ((addwhat & CC_SPECIALS)  &&  (hn->flags & PM_SPECIAL))  ||
1984		  ((addwhat & CC_PARAMS)    && !(hn->flags & PM_EXPORTED))) &&
1985		 !pm->level) ||
1986		((( addwhat & CC_SHFUNCS)				  ||
1987		  ( addwhat & CC_BUILTINS)				  ||
1988		  ( addwhat & CC_EXTCMDS)				  ||
1989		  ( addwhat & CC_RESWDS)				  ||
1990		  ((addwhat & CC_ALREG)   && !(hn->flags & ALIAS_GLOBAL)) ||
1991		  ((addwhat & CC_ALGLOB)  &&  (hn->flags & ALIAS_GLOBAL))) &&
1992		 (((addwhat & CC_DISCMDS) && (hn->flags & DISABLED)) ||
1993		  ((addwhat & CC_EXCMDS)  && !(hn->flags & DISABLED)))) ||
1994		((addwhat & CC_BINDINGS) && !(hn->flags & DISABLED))))) {
1995	char *p1, *s1, *p2, *s2;
1996
1997	if (addwhat == CC_QUOTEFLAG) {
1998	    p1 = qrpre; s1 = qrsuf;
1999	    p2 = rpre;  s2 = rsuf;
2000	} else {
2001	    p1 = qlpre; s1 = qlsuf;
2002	    p2 = lpre;  s2 = lsuf;
2003	}
2004	p1 = multiquote(p1, 1); s1 = multiquote(s1, 1);
2005	p2 = multiquote(p2, 1); s2 = multiquote(s2, 1);
2006	bpt = bpl;
2007	bst = bsl;
2008
2009	if (!(ms = comp_match(p1, s1, s, patcomp, &lc,
2010			      (addwhat == CC_QUOTEFLAG),
2011			      &bpl, strlen(p1), &bsl, strlen(s1),
2012			      &isexact))) {
2013	    bpl = bpt;
2014	    bsl = bst;
2015	    if (!(ms = comp_match(p2, s2, s, NULL, &lc,
2016				  (addwhat == CC_QUOTEFLAG),
2017				  &bpl, strlen(p2), &bsl, strlen(s2),
2018				  &isexact)))
2019		return;
2020	}
2021    }
2022    if (!ms)
2023	return;
2024    add_match_data(isalt, ms, s, lc, ipre, ripre, isuf,
2025		   (incompfunc ? dupstring(curcc->prefix) : curcc->prefix),
2026		   prpre,
2027		   (isfile ? lppre : NULL), NULL,
2028		   (isfile ? lpsuf : NULL), NULL,
2029		   (incompfunc ? dupstring(curcc->suffix) : curcc->suffix),
2030		   (mflags | isfile), isexact);
2031}
2032
2033/**/
2034static void
2035maketildelist(void)
2036{
2037    /* add all the usernames to the named directory table */
2038    nameddirtab->filltable(nameddirtab);
2039
2040    scanhashtable(nameddirtab, 0, (addwhat==-1) ? 0 : ND_USERNAME, 0,
2041		  addhnmatch, 0);
2042}
2043
2044/* This does the check for compctl -x `n' and `N' patterns. */
2045
2046/**/
2047int
2048getcpat(char *str, int cpatindex, char *cpat, int class)
2049{
2050    char *s, *t, *p;
2051    int d = 0;
2052
2053    if (!str || !*str)
2054	return -1;
2055
2056    cpat = rembslash(cpat);
2057
2058    if (!cpatindex)
2059	cpatindex++, d = 0;
2060    else if ((d = (cpatindex < 0)))
2061	cpatindex = -cpatindex;
2062
2063    for (s = d ? str + strlen(str) - 1 : str;
2064	 d ? (s >= str) : *s;
2065	 d ? s-- : s++) {
2066	for (t = s, p = cpat; *t && *p; p++) {
2067	    if (class) {
2068		if (*p == *s && !--cpatindex)
2069		    return (int)(s - str + 1);
2070	    } else if (*t++ != *p)
2071		break;
2072	}
2073	if (!class && !*p && !--cpatindex)
2074	    return t - str;
2075    }
2076    return -1;
2077}
2078
2079/* Dump a hash table (without sorting).  For each element the addmatch  *
2080 * function is called and at the beginning the addwhat variable is set. *
2081 * This could be done using scanhashtable(), but this is easy and much  *
2082 * more efficient.                                                      */
2083
2084/**/
2085static void
2086dumphashtable(HashTable ht, int what)
2087{
2088    HashNode hn;
2089    int i;
2090
2091    addwhat = what;
2092
2093    for (i = 0; i < ht->hsize; i++)
2094	for (hn = ht->nodes[i]; hn; hn = hn->next)
2095	    addmatch(dupstring(hn->nam), (char *) hn);
2096}
2097
2098/* ScanFunc used by maketildelist() et al. */
2099
2100/**/
2101static void
2102addhnmatch(HashNode hn, UNUSED(int flags))
2103{
2104    addmatch(hn->nam, NULL);
2105}
2106
2107/* Perform expansion on the given string and return the result. *
2108 * During this errors are not reported.                         */
2109
2110/**/
2111static char *
2112getreal(char *str)
2113{
2114    LinkList l = newlinklist();
2115    int ne = noerrs;
2116
2117    noerrs = 1;
2118    addlinknode(l, dupstring(str));
2119    prefork(l, 0);
2120    noerrs = ne;
2121    if (!errflag && nonempty(l) &&
2122	((char *) peekfirst(l)) && ((char *) peekfirst(l))[0])
2123	return dupstring(peekfirst(l));
2124    errflag = 0;
2125
2126    return dupstring(str);
2127}
2128
2129/* This reads a directory and adds the files to the list of  *
2130 * matches.  The parameters say which files should be added. */
2131
2132/**/
2133static void
2134gen_matches_files(int dirs, int execs, int all)
2135{
2136    DIR *d;
2137    struct stat buf;
2138    char *n, p[PATH_MAX], *q = NULL, *e, *pathpref;
2139    LinkList l = NULL;
2140    int ns = 0, ng = opts[NULLGLOB], test, aw = addwhat, pathpreflen;
2141
2142    opts[NULLGLOB] = 1;
2143
2144    if (*psuf) {
2145	/* If there is a path suffix, check if it doesn't have a `*' or *
2146	 * `)' at the end (this is used to determine if we should use   *
2147	 * globbing).                                                   */
2148	q = psuf + strlen(psuf) - 1;
2149	ns = !(*q == Star || *q == Outpar);
2150	l = newlinklist();
2151	/* And generate only directory names. */
2152	dirs = 1;
2153	all = execs = 0;
2154    }
2155    /* Open directory. */
2156    if (prpre && *prpre) {
2157	pathpref = dupstring(prpre);
2158	unmetafy(pathpref, &pathpreflen);
2159	/* system needs NULL termination, not provided by unmetafy */
2160	pathpref[pathpreflen] = '\0';
2161    } else {
2162	pathpref = NULL;
2163	pathpreflen = 0;
2164    }
2165    if ((d = opendir(pathpref ? pathpref : "."))) {
2166	/* If we search only special files, prepare a path buffer for stat. */
2167	if (!all && pathpreflen) {
2168	    /* include null byte we carefully added */
2169	    memcpy(p, pathpref, pathpreflen+1);
2170	}
2171	q = p + pathpreflen;
2172	/* Fine, now read the directory. */
2173	while ((n = zreaddir(d, 1)) && !errflag) {
2174	    /* Ignore files beginning with `.' unless the thing we found on *
2175	     * the command line also starts with a dot or GLOBDOTS is set.  */
2176	    if (*n != '.' || *fpre == '.' || isset(GLOBDOTS)) {
2177		addwhat = execs ? -8 : -5;
2178		if (filecomp)
2179		    /* If we have a pattern for the filename check, use it. */
2180		    test = pattry(filecomp, n);
2181		else {
2182		    /* Otherwise use the prefix and suffix strings directly. */
2183		    e = n + strlen(n) - fsl;
2184		    if ((test = !strncmp(n, fpre, fpl)))
2185			test = !strcmp(e, fsuf);
2186		    if (!test && mstack) {
2187			test = 1;
2188			addwhat = CC_FILES;
2189		    }
2190		}
2191		/* Filename didn't match? */
2192		if (!test)
2193		    continue;
2194		if (!all) {
2195		    char *ums;
2196		    int umlen;
2197		    /* We still have to check the file type, so prepare *
2198		     * the path buffer by appending the filename.       */
2199		    ums = dupstring(n);
2200		    unmetafy(ums, &umlen);
2201		    memcpy(q, ums, umlen);
2202		    q[umlen] = '\0';
2203		    /* And do the stat. */
2204		    if (stat(p, &buf) < 0)
2205			continue;
2206		}
2207		if (all ||
2208		    (dirs && S_ISDIR(buf.st_mode)) ||
2209		    (execs && S_ISREG(buf.st_mode) && (buf.st_mode&S_IXUGO))) {
2210		    /* If we want all files or the file has the right type... */
2211		    if (*psuf) {
2212			/* We have to test for a path suffix. */
2213			int o = strlen(p), tt;
2214
2215			/* Append it to the path buffer. */
2216			strcpy(p + o, psuf);
2217
2218			/* Do we have to use globbing? */
2219			if (ispattern ||
2220			    (ns && comppatmatch && *comppatmatch)) {
2221			    /* Yes, so append a `*' if needed. */
2222			    if (ns && comppatmatch && *comppatmatch == '*') {
2223				int tl = strlen(p);
2224
2225				p[tl] = Star;
2226				p[tl + 1] = '\0';
2227			    }
2228			    /* Do the globbing... */
2229			    remnulargs(p);
2230			    addlinknode(l, p);
2231			    globlist(l, 0);
2232			    /* And see if that produced a filename. */
2233			    tt = nonempty(l);
2234			    while (ugetnode(l));
2235			} else
2236			    /* Otherwise just check, if we have access *
2237			     * to the file.                            */
2238			    tt = !access(p, F_OK);
2239
2240			p[o] = '\0';
2241			if (tt)
2242			    /* Ok, we can add the filename to the *
2243			     * list of matches.                   */
2244			    addmatch(dupstring(n), NULL);
2245		    } else
2246			/* We want all files, so just add the name *
2247			 * to the matches.                         */
2248			addmatch(dupstring(n), NULL);
2249		}
2250	    }
2251	}
2252	closedir(d);
2253    }
2254    opts[NULLGLOB] = ng;
2255    addwhat = aw;
2256}
2257
2258/* This returns the node with the given data. */
2259/* ...should probably be moved to linklist.c. */
2260
2261static LinkNode
2262findnode(LinkList list, void *dat)
2263{
2264    LinkNode tmp = firstnode(list);
2265
2266    while (tmp && getdata(tmp) != dat) incnode(tmp);
2267
2268    return tmp;
2269}
2270
2271/* A simple counter to avoid endless recursion between old and new style *
2272 * completion. */
2273
2274static int cdepth = 0;
2275
2276#define MAX_CDEPTH 16
2277
2278/**/
2279static int
2280makecomplistctl(int flags)
2281{
2282    Heap oldheap;
2283    int ret;
2284
2285    if (cdepth == MAX_CDEPTH)
2286	return 0;
2287
2288    cdepth++;
2289    SWITCHHEAPS(oldheap, compheap) {
2290	int ooffs = offs, lip, lp;
2291	char *str = comp_str(&lip, &lp, 0), *t;
2292	char *os = cmdstr, **ow = clwords, **p, **q, qc;
2293	int on = clwnum, op = clwpos, ois =  instring, oib = inbackt;
2294	char *oisuf = isuf, *oqp = qipre, *oqs = qisuf, *oaq = autoq;
2295	char buf[3];
2296
2297	if (compquote && (qc = *compquote)) {
2298	    if (qc == '`') {
2299		instring = QT_NONE;
2300		/*
2301		 * Yes, inbackt has always been set to zero here.  I'm
2302		 * sure there's a simple explanation.
2303		 */
2304		inbackt = 0;
2305		autoq = "";
2306	    } else {
2307		switch (qc) {
2308		case '\'':
2309		    instring = QT_SINGLE;
2310		    break;
2311
2312		case '"':
2313		    instring = QT_DOUBLE;
2314		    break;
2315
2316		case '$':
2317		    instring = QT_DOLLARS;
2318		    break;
2319		}
2320		inbackt = 0;
2321		strcpy(buf, *compquote == '$' ? compquote+1 : compquote);
2322		autoq = buf;
2323	    }
2324	} else {
2325	    instring = QT_NONE;
2326	    inbackt = 0;
2327	    autoq = "";
2328	}
2329	qipre = ztrdup(compqiprefix ? compqiprefix : "");
2330	qisuf = ztrdup(compqisuffix ? compqisuffix : "");
2331	isuf = dupstring(compisuffix);
2332	ctokenize(isuf);
2333	remnulargs(isuf);
2334	clwnum = arrlen(compwords);
2335	clwpos = compcurrent - 1;
2336	cmdstr = ztrdup(compwords[0]);
2337	clwords = (char **) zalloc((clwnum + 1) * sizeof(char *));
2338	for (p = compwords, q = clwords; *p; p++, q++) {
2339	    t = dupstring(*p);
2340	    tokenize(t);
2341	    remnulargs(t);
2342	    *q = ztrdup(t);
2343	}
2344	*q = NULL;
2345	offs = lip + lp;
2346	incompfunc = 2;
2347	ret = makecomplistglobal(str, !clwpos, COMP_COMPLETE, flags);
2348	incompfunc = 1;
2349	isuf = oisuf;
2350	zsfree(qipre);
2351	zsfree(qisuf);
2352	qipre = oqp;
2353	qisuf = oqs;
2354	instring = ois;
2355	inbackt = oib;
2356	autoq = oaq;
2357	offs = ooffs;
2358	zsfree(cmdstr);
2359	freearray(clwords);
2360	cmdstr = os;
2361	clwords = ow;
2362	clwnum = on;
2363	clwpos = op;
2364    } SWITCHBACKHEAPS(oldheap);
2365    cdepth--;
2366
2367    return ret;
2368}
2369
2370/* This function gets the compctls for the given command line and *
2371 * adds all completions for them. */
2372
2373/**/
2374static int
2375makecomplistglobal(char *os, int incmd, UNUSED(int lst), int flags)
2376{
2377    Compctl cc = NULL;
2378    char *s;
2379
2380    ccont = CC_CCCONT;
2381    cc_dummy.suffix = NULL;
2382
2383    if (linwhat == IN_ENV) {
2384        /* Default completion for parameter values. */
2385	if (!(flags & CFN_DEFAULT)) {
2386	    cc = &cc_default;
2387	    keypm = NULL;
2388	}
2389    } else if (linwhat == IN_MATH) {
2390	if (!(flags & CFN_DEFAULT)) {
2391	    if (insubscr >= 2) {
2392		/* Inside subscript of assoc array, complete keys. */
2393		cc_dummy.mask = 0;
2394		cc_dummy.suffix = (insubscr == 2 ? "]" : "");
2395	    } else {
2396		/* Other math environment, complete paramete names. */
2397		keypm = NULL;
2398		cc_dummy.mask = CC_PARAMS;
2399	    }
2400	    cc = &cc_dummy;
2401	    cc_dummy.refc = 10000;
2402	}
2403    } else if (linwhat == IN_COND) {
2404	/* We try to be clever here: in conditions we complete option   *
2405	 * names after a `-o', file names after `-nt', `-ot', and `-ef' *
2406	 * and file names and parameter names elsewhere.                */
2407	if (!(flags & CFN_DEFAULT)) {
2408	    s = clwpos ? clwords[clwpos - 1] : "";
2409	    cc_dummy.mask = !strcmp("-o", s) ? CC_OPTIONS :
2410		((*s == '-' && s[1] && !s[2]) ||
2411		 !strcmp("-nt", s) ||
2412		 !strcmp("-ot", s) ||
2413		 !strcmp("-ef", s)) ? CC_FILES :
2414		(CC_FILES | CC_PARAMS);
2415	    cc = &cc_dummy;
2416	    cc_dummy.refc = 10000;
2417	    keypm = NULL;
2418	}
2419    } else if (linredir) {
2420	if (!(flags & CFN_DEFAULT)) {
2421	    /* In redirections use default completion. */
2422	    cc = &cc_default;
2423	    keypm = NULL;
2424	}
2425    } else {
2426	/* Otherwise get the matches for the command. */
2427	keypm = NULL;
2428	return makecomplistcmd(os, incmd, flags);
2429    }
2430    if (cc) {
2431	/* First, use the -T compctl. */
2432	if (!(flags & CFN_FIRST)) {
2433	    makecomplistcc(&cc_first, os, incmd);
2434
2435	    if (!(ccont & CC_CCCONT))
2436		return 0;
2437	}
2438	makecomplistcc(cc, os, incmd);
2439	return 1;
2440    }
2441    return 0;
2442}
2443
2444/* This produces the matches for a command. */
2445
2446/**/
2447static int
2448makecomplistcmd(char *os, int incmd, int flags)
2449{
2450    Compctl cc;
2451    Compctlp ccp;
2452    char *s;
2453    int ret = 0;
2454
2455    /* First, use the -T compctl. */
2456    if (!(flags & CFN_FIRST)) {
2457	makecomplistcc(&cc_first, os, incmd);
2458
2459	if (!(ccont & CC_CCCONT))
2460	    return 0;
2461    }
2462    /* Then search the pattern compctls, with the command name and the *
2463     * full pathname of the command. */
2464    if (cmdstr) {
2465	ret |= makecomplistpc(os, incmd);
2466	if (!(ccont & CC_CCCONT))
2467	    return ret;
2468    }
2469    /* If the command string starts with `=', try the path name of the *
2470     * command. */
2471    if (cmdstr && cmdstr[0] == Equals) {
2472	char *c = findcmd(cmdstr + 1, 1);
2473
2474	if (c) {
2475	    zsfree(cmdstr);
2476	    cmdstr = ztrdup(c);
2477	}
2478    }
2479
2480    /* Find the compctl for this command, trying the full name and then *
2481     * the trailing pathname component. If that doesn't yield anything, *
2482     * use default completion. */
2483    if (incmd)
2484	cc = &cc_compos;
2485    else if (!(cmdstr &&
2486	  (((ccp = (Compctlp) compctltab->getnode(compctltab, cmdstr)) &&
2487	    (cc = ccp->cc)) ||
2488	   ((s = dupstring(cmdstr)) && remlpaths(&s) &&
2489	    (ccp = (Compctlp) compctltab->getnode(compctltab, s)) &&
2490	    (cc = ccp->cc))))) {
2491	if (flags & CFN_DEFAULT)
2492	    return ret;
2493	cc = &cc_default;
2494    } else
2495	ret|= 1;
2496    makecomplistcc(cc, os, incmd);
2497    return ret;
2498}
2499
2500/* This adds the matches for the pattern compctls. */
2501
2502/**/
2503static int
2504makecomplistpc(char *os, int incmd)
2505{
2506    Patcomp pc;
2507    Patprog pat;
2508    char *s;
2509    int ret = 0;
2510
2511    s = ((shfunctab->getnode(shfunctab, cmdstr) ||
2512	  builtintab->getnode(builtintab, cmdstr)) ? NULL : findcmd(cmdstr, 1));
2513
2514    for (pc = patcomps; pc; pc = pc->next) {
2515	if ((pat = patcompile(pc->pat, PAT_STATIC, NULL)) &&
2516	    (pattry(pat, cmdstr) ||
2517	     (s && pattry(pat, s)))) {
2518	    makecomplistcc(pc->cc, os, incmd);
2519	    ret |= 2;
2520	    if (!(ccont & CC_CCCONT))
2521		return ret;
2522	}
2523    }
2524    return ret;
2525}
2526
2527/* This produces the matches for one compctl. */
2528
2529/**/
2530static void
2531makecomplistcc(Compctl cc, char *s, int incmd)
2532{
2533    cc->refc++;
2534    if (!ccused)
2535	ccused = newlinklist();
2536    addlinknode(ccused, cc);
2537
2538    ccont = 0;
2539
2540    makecomplistor(cc, s, incmd, 0, 0);
2541}
2542
2543/* This adds the completions for one run of [x]or'ed completions. */
2544
2545/**/
2546static void
2547makecomplistor(Compctl cc, char *s, int incmd, int compadd, int sub)
2548{
2549    int mn, ct, um = usemenu;
2550
2551    /* Loop over xors. */
2552    do {
2553	mn = mnum;
2554
2555	/* Loop over ors. */
2556	do {
2557	    /* Reset the range information if we are not in a sub-list. */
2558	    if (!sub) {
2559		brange = 0;
2560		erange = clwnum - 1;
2561	    }
2562	    usemenu = 0;
2563	    makecomplistlist(cc, s, incmd, compadd);
2564	    um |= usemenu;
2565
2566	    ct = cc->mask2 & CC_XORCONT;
2567
2568	    cc = cc->xor;
2569	} while (cc && ct);
2570
2571	/* Stop if we got some matches. */
2572	if (mn != mnum)
2573	    break;
2574	if (cc) {
2575	    ccont &= ~(CC_DEFCONT | CC_PATCONT);
2576	    if (!sub)
2577		ccont &= ~CC_CCCONT;
2578	}
2579    } while (cc);
2580
2581    usemenu = um;
2582}
2583
2584/* This dispatches for simple and extended completion. */
2585
2586/**/
2587static void
2588makecomplistlist(Compctl cc, char *s, int incmd, int compadd)
2589{
2590    int oloffs = offs, owe = we, owb = wb, ocs = zlemetacs;
2591
2592    METACHECK();
2593
2594    if (cc->ext)
2595	/* Handle extended completion. */
2596	makecomplistext(cc, s, incmd);
2597    else
2598	/* Only normal flags. */
2599	makecomplistflags(cc, s, incmd, compadd);
2600
2601    /* Reset some information variables for the next try. */
2602    errflag = 0;
2603    offs = oloffs;
2604    wb = owb;
2605    we = owe;
2606    zlemetacs = ocs;
2607}
2608
2609/* This add matches for extended completion patterns */
2610
2611/**/
2612static void
2613makecomplistext(Compctl occ, char *os, int incmd)
2614{
2615    Compctl compc;
2616    Compcond or, cc;
2617    Patprog pprog;
2618    int compadd, m = 0, d = 0, t, tt, i, j, a, b, ins;
2619    char *sc = NULL, *s, *ss;
2620
2621    ins = (instring != QT_NONE ? instring : (inbackt ? QT_BACKTICK : 0));
2622
2623    /* This loops over the patterns separated by `-'s. */
2624    for (compc = occ->ext; compc; compc = compc->next) {
2625	compadd = t = brange = 0;
2626	erange = clwnum - 1;
2627	/* This loops over OR'ed patterns. */
2628	for (cc = compc->cond; cc && !t; cc = or) {
2629	    or = cc->or;
2630	    /* This loops over AND'ed patterns. */
2631	    for (t = 1; cc && t; cc = cc->and) {
2632		/* And this loops over [...] pairs. */
2633		for (t = i = 0; i < cc->n && !t; i++) {
2634		    s = NULL;
2635		    brange = 0;
2636		    erange = clwnum - 1;
2637		    switch (cc->type) {
2638		    case CCT_QUOTE:
2639			t = ((cc->u.s.s[i][0] == 's' && ins == QT_SINGLE) ||
2640			     (cc->u.s.s[i][0] == 'd' && ins == QT_DOUBLE) ||
2641			     (cc->u.s.s[i][0] == 'b' && ins == QT_BACKTICK));
2642			break;
2643		    case CCT_POS:
2644			tt = clwpos;
2645			goto cct_num;
2646		    case CCT_NUMWORDS:
2647			tt = clwnum;
2648		    cct_num:
2649			if ((a = cc->u.r.a[i]) < 0)
2650			    a += clwnum;
2651			if ((b = cc->u.r.b[i]) < 0)
2652			    b += clwnum;
2653			if (cc->type == CCT_POS)
2654			    brange = a, erange = b;
2655			t = (tt >= a && tt <= b);
2656			break;
2657		    case CCT_CURSUF:
2658		    case CCT_CURPRE:
2659			s = ztrdup(clwpos < clwnum ? os : "");
2660			untokenize(s);
2661			if (isset(COMPLETEINWORD)) s[offs] = '\0';
2662			sc = rembslash(cc->u.s.s[i]);
2663			a = strlen(sc);
2664			if (!strncmp(s, sc, a)) {
2665			    compadd = (cc->type == CCT_CURSUF ? a : 0);
2666			    t = 1;
2667			}
2668			break;
2669		    case CCT_CURSUB:
2670		    case CCT_CURSUBC:
2671			if (clwpos < 0 || clwpos >= clwnum)
2672			    t = 0;
2673			else {
2674			    s = ztrdup(os);
2675			    untokenize(s);
2676			    if (isset(COMPLETEINWORD)) s[offs] = '\0';
2677			    a = getcpat(s,
2678					cc->u.s.p[i],
2679					cc->u.s.s[i],
2680					cc->type == CCT_CURSUBC);
2681			    if (a != -1)
2682				compadd = a, t = 1;
2683			}
2684			break;
2685
2686		    case CCT_CURPAT:
2687		    case CCT_CURSTR:
2688			tt = clwpos;
2689			goto cct_str;
2690		    case CCT_WORDPAT:
2691		    case CCT_WORDSTR:
2692			tt = 0;
2693		    cct_str:
2694			if ((a = tt + cc->u.s.p[i]) < 0)
2695			    a += clwnum;
2696			s = ztrdup((a < 0 || a >= clwnum) ? "" :
2697				   clwords[a]);
2698			untokenize(s);
2699
2700			if (cc->type == CCT_CURPAT ||
2701			    cc->type == CCT_WORDPAT) {
2702			    tokenize(ss = dupstring(cc->u.s.s[i]));
2703			    t = ((pprog = patcompile(ss, PAT_STATIC, NULL)) &&
2704				 pattry(pprog, s));
2705			} else
2706			    t = (!strcmp(s, rembslash(cc->u.s.s[i])));
2707			break;
2708		    case CCT_RANGESTR:
2709		    case CCT_RANGEPAT:
2710			if (cc->type == CCT_RANGEPAT)
2711			    tokenize(sc = dupstring(cc->u.l.a[i]));
2712			for (j = clwpos - 1; j > 0; j--) {
2713			    untokenize(s = ztrdup(clwords[j]));
2714			    if (cc->type == CCT_RANGESTR)
2715				sc = rembslash(cc->u.l.a[i]);
2716			    if (cc->type == CCT_RANGESTR ?
2717				!strncmp(s, sc, strlen(sc)) :
2718				((pprog = patcompile(sc, PAT_STATIC, 0)) &&
2719				 pattry(pprog, s))) {
2720				zsfree(s);
2721				brange = j + 1;
2722				t = 1;
2723				break;
2724			    }
2725			    zsfree(s);
2726			}
2727			if (t && cc->u.l.b[i]) {
2728			    if (cc->type == CCT_RANGEPAT)
2729				tokenize(sc = dupstring(cc->u.l.b[i]));
2730			    for (j++; j < clwnum; j++) {
2731				untokenize(s = ztrdup(clwords[j]));
2732				if (cc->type == CCT_RANGESTR)
2733				    sc = rembslash(cc->u.l.b[i]);
2734				if (cc->type == CCT_RANGESTR ?
2735				    !strncmp(s, sc, strlen(sc)) :
2736				    ((pprog = patcompile(sc, PAT_STATIC, 0)) &&
2737				     pattry(pprog, s))) {
2738				    zsfree(s);
2739				    erange = j - 1;
2740				    t = clwpos <= erange;
2741				    break;
2742				}
2743				zsfree(s);
2744			    }
2745			}
2746			s = NULL;
2747		    }
2748		    zsfree(s);
2749		}
2750	    }
2751	}
2752	if (t) {
2753	    /* The patterns matched, use the flags. */
2754	    m = 1;
2755	    ccont &= ~(CC_PATCONT | CC_DEFCONT);
2756	    makecomplistor(compc, os, incmd, compadd, 1);
2757	    if (!d && (ccont & CC_DEFCONT)) {
2758		d = 1;
2759		compadd = 0;
2760		brange = 0;
2761		erange = clwnum - 1;
2762		makecomplistflags(occ, os, incmd, 0);
2763	    }
2764	    if (!(ccont & CC_PATCONT))
2765		break;
2766	}
2767    }
2768    /* If no pattern matched, use the standard flags. */
2769    if (!m) {
2770	compadd = 0;
2771	brange = 0;
2772	erange = clwnum - 1;
2773	makecomplistflags(occ, os, incmd, 0);
2774    }
2775}
2776
2777/**/
2778static int
2779sep_comp_string(char *ss, char *s, int noffs)
2780{
2781    LinkList foo = newlinklist();
2782    LinkNode n;
2783    int owe = we, owb = wb, ocs = zlemetacs, swb, swe, scs, soffs, ne = noerrs;
2784    int sl = strlen(ss), tl, got = 0, i = 0, cur = -1, oll = zlemetall, remq;
2785    int ois = instring, oib = inbackt, ona = noaliases;
2786    char *tmp, *p, *ns, *ol = zlemetaline, sav, *oaq = autoq;
2787    char *qp, *qs, *ts;
2788
2789    swb = swe = soffs = 0;
2790    ns = NULL;
2791
2792    METACHECK();
2793
2794    /* Put the string in the lexer buffer and call the lexer to *
2795     * get the words we have to expand.                        */
2796    addedx = 1;
2797    noerrs = 1;
2798    lexsave();
2799    lexflags = LEXFLAGS_ZLE;
2800    tmp = (char *) zhalloc(tl = sl + 3 + strlen(s));
2801    strcpy(tmp, ss);
2802    tmp[sl] = ' ';
2803    memcpy(tmp + sl + 1, s, noffs);
2804    tmp[(scs = zlemetacs = sl + 1 + noffs)] = 'x';
2805    strcpy(tmp + sl + 2 + noffs, s + noffs);
2806    if ((remq = (*compqstack == QT_BACKSLASH)))
2807	tmp = rembslash(tmp);
2808    inpush(dupstrspace(tmp), 0, NULL);
2809    zlemetaline = tmp;
2810    zlemetall = tl - 1;
2811    strinbeg(0);
2812    noaliases = 1;
2813    do {
2814	ctxtlex();
2815	if (tok == LEXERR) {
2816	    int j;
2817
2818	    if (!tokstr)
2819		break;
2820	    for (j = 0, p = tokstr; *p; p++)
2821		if (*p == Snull || *p == Dnull)
2822		    j++;
2823	    if (j & 1) {
2824		tok = STRING;
2825		if (p > tokstr && p[-1] == ' ')
2826		    p[-1] = '\0';
2827	    }
2828	}
2829	if (tok == ENDINPUT || tok == LEXERR)
2830	    break;
2831	if (tokstr && *tokstr)
2832	    addlinknode(foo, (p = ztrdup(tokstr)));
2833	else
2834	    p = NULL;
2835	if (!got && !lexflags) {
2836	    DPUTS(!p, "no current word in substr");
2837	    got = 1;
2838	    cur = i;
2839	    swb = wb - 1;
2840	    swe = we - 1;
2841	    soffs = zlemetacs - swb;
2842	    chuck(p + soffs);
2843	    ns = dupstring(p);
2844	}
2845	i++;
2846    } while (tok != ENDINPUT && tok != LEXERR);
2847    noaliases = ona;
2848    strinend();
2849    inpop();
2850    errflag = 0;
2851    noerrs = ne;
2852    lexrestore();
2853    wb = owb;
2854    we = owe;
2855    zlemetacs = ocs;
2856    zlemetaline = ol;
2857    zlemetall = oll;
2858    if (cur < 0 || i < 1)
2859	return 1;
2860    owb = offs;
2861    offs = soffs;
2862    if ((p = check_param(ns, 0, 1))) {
2863	for (p = ns; *p; p++)
2864	    if (*p == Dnull)
2865		*p = '"';
2866	    else if (*p == Snull)
2867		*p = '\'';
2868    }
2869    offs = owb;
2870
2871    untokenize(ts = dupstring(ns));
2872
2873    if (*ns == Snull || *ns == Dnull ||
2874	((*ns == String || *ns == Qstring) && ns[1] == Snull)) {
2875	char *tsptr = ts, *nsptr = ns, sav;
2876	switch (*ns) {
2877	case Snull:
2878	    instring = QT_SINGLE;
2879	    break;
2880
2881	case Dnull:
2882	    instring = QT_DOUBLE;
2883	    break;
2884
2885	default:
2886	    instring = QT_DOLLARS;
2887	    nsptr++;
2888	    tsptr++;
2889	    break;
2890	}
2891
2892	inbackt = 0;
2893	swb++;
2894	if (nsptr[strlen(nsptr) - 1] == *nsptr && nsptr[1])
2895	    swe--;
2896	sav = *++tsptr;
2897	*tsptr = '\0';
2898	autoq = compqstack[1] ? "" : multiquote(ts, 1);
2899	*(ts = tsptr) = sav;
2900    } else {
2901	instring = QT_NONE;
2902	autoq = "";
2903    }
2904    for (p = ns, i = swb; *p; p++, i++) {
2905	if (inull(*p)) {
2906	    if (i < scs) {
2907		soffs--;
2908		if (remq && *p == Bnull && p[1])
2909		    swb -= 2;
2910	    }
2911	    if (p[1] || *p != Bnull) {
2912		if (*p == Bnull) {
2913		    if (scs == i + 1)
2914			scs++, soffs++;
2915		} else {
2916		    if (scs > i--)
2917			scs--;
2918		}
2919	    } else {
2920		if (scs == swe)
2921		    scs--;
2922	    }
2923	    chuck(p--);
2924	}
2925    }
2926    ns = ts;
2927
2928    if (instring != QT_NONE && strchr(compqstack, QT_BACKSLASH)) {
2929	int rl = strlen(ns), ql = strlen(multiquote(ns, !!compqstack[1]));
2930
2931	if (ql > rl)
2932	    swb -= ql - rl;
2933    }
2934    sav = s[(i = swb - sl - 1)];
2935    s[i] = '\0';
2936    qp = tricat(qipre, multiquote(s, 0), "");
2937    s[i] = sav;
2938    if (swe < swb)
2939	swe = swb;
2940    swe -= sl + 1;
2941    sl = strlen(s);
2942    if (swe > sl) {
2943	swe = sl;
2944	if ((int)strlen(ns) > swe - swb + 1)
2945	    ns[swe - swb + 1] = '\0';
2946    }
2947    qs = tricat(multiquote(s + swe, 0), qisuf, "");
2948    sl = strlen(ns);
2949    if (soffs > sl)
2950	soffs = sl;
2951
2952    {
2953	char **ow = clwords, *os = cmdstr, *oqp = qipre, *oqs = qisuf;
2954	char *oqst = compqstack, compnewchar[2];
2955	int olws = clwsize, olwn = clwnum, olwp = clwpos;
2956	int obr = brange, oer = erange, oof = offs;
2957	unsigned long occ = ccont;
2958
2959	compnewchar[0] = (char)(instring != QT_NONE ? (char)instring :
2960				QT_BACKSLASH);
2961	compnewchar[1] = '\0';
2962	compqstack = tricat(compnewchar, compqstack, "");
2963
2964	clwsize = clwnum = countlinknodes(foo);
2965	clwords = (char **) zalloc((clwnum + 1) * sizeof(char *));
2966	for (n = firstnode(foo), i = 0; n; incnode(n), i++) {
2967	    p = clwords[i] = (char *) getdata(n);
2968	    untokenize(p);
2969	}
2970	clwords[i] = NULL;
2971	clwpos = cur;
2972	cmdstr = ztrdup(clwords[0]);
2973	brange = 0;
2974	erange = clwnum - 1;
2975	qipre = qp;
2976	qisuf = qs;
2977	offs = soffs;
2978	ccont = CC_CCCONT;
2979	makecomplistcmd(ns, !clwpos, CFN_FIRST);
2980	ccont = occ;
2981	offs = oof;
2982	zsfree(cmdstr);
2983	cmdstr = os;
2984	freearray(clwords);
2985	clwords = ow;
2986	clwsize = olws;
2987	clwnum = olwn;
2988	clwpos = olwp;
2989	brange = obr;
2990	erange = oer;
2991	zsfree(qipre);
2992	qipre = oqp;
2993	zsfree(qisuf);
2994	qisuf = oqs;
2995	zsfree(compqstack);
2996	compqstack = oqst;
2997    }
2998    autoq = oaq;
2999    instring = ois;
3000    inbackt = oib;
3001
3002    return 0;
3003}
3004
3005/* This adds the completions for the flags in the given compctl. */
3006
3007/**/
3008static void
3009makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
3010{
3011    int t, sf1, sf2, ooffs, um = usemenu, delit, oaw, gflags;
3012    int mn = mnum, ohp = haspattern;
3013    char *p, *sd = NULL, *tt, *s1, *s2, *os =  dupstring(s);
3014    struct cmlist ms;
3015
3016    ccont |= (cc->mask2 & (CC_CCCONT | CC_DEFCONT | CC_PATCONT));
3017
3018    if (incompfunc != 1 && ccstack && findnode(ccstack, cc))
3019	return;
3020
3021    if (!ccstack)
3022	ccstack = newlinklist();
3023    addlinknode(ccstack, cc);
3024
3025    if (incompfunc != 1 && allccs) {
3026	if (findnode(allccs, cc)) {
3027	    uremnode(ccstack, firstnode(ccstack));
3028	    return;
3029	}
3030	addlinknode(allccs, cc);
3031    }
3032    /* Go to the end of the word if complete_in_word is not set. */
3033    if (unset(COMPLETEINWORD) && zlemetacs != we)
3034	zlemetacs = we, offs = strlen(s);
3035
3036    s = dupstring(s);
3037    delit = ispattern = 0;
3038    usemenu = um;
3039    patcomp = filecomp = NULL;
3040    rpre = rsuf = lpre = lsuf = ppre = psuf = lppre = lpsuf =
3041	fpre = fsuf = ipre = ripre = prpre =
3042	qfpre = qfsuf = qrpre = qrsuf = qlpre = qlsuf = NULL;
3043
3044    curcc = cc;
3045
3046    mflags = 0;
3047    gflags = (((cc->mask2 & CC_NOSORT ) ? CGF_NOSORT  : 0) |
3048	      ((cc->mask2 & CC_UNIQALL) ? CGF_UNIQALL : 0) |
3049	      ((cc->mask2 & CC_UNIQCON) ? CGF_UNIQCON : 0));
3050    if (cc->gname) {
3051	endcmgroup(NULL);
3052	begcmgroup(cc->gname, gflags);
3053    }
3054    if (cc->ylist) {
3055	endcmgroup(NULL);
3056	begcmgroup(NULL, gflags);
3057    }
3058    if (cc->mask & CC_REMOVE)
3059	mflags |= CMF_REMOVE;
3060    if (cc->explain) {
3061	curexpl = (Cexpl) zhalloc(sizeof(struct cexpl));
3062	curexpl->count = curexpl->fcount = 0;
3063    } else
3064	curexpl = NULL;
3065    /* compadd is the number of characters we have to ignore at the  *
3066     * beginning of the word.                                        */
3067    if (compadd) {
3068	ipre = dupstring(s);
3069	ipre[compadd] = '\0';
3070	untokenize(ipre);
3071	wb += compadd;
3072	s += compadd;
3073	if ((offs -= compadd) < 0) {
3074	    /* It's bigger than our word prefix, so we can't help here... */
3075	    uremnode(ccstack, firstnode(ccstack));
3076	    return;
3077	}
3078    } else
3079	ipre = NULL;
3080
3081    if (cc->matcher) {
3082	ms.next = mstack;
3083	ms.matcher = cc->matcher;
3084	mstack = &ms;
3085
3086	if (!mnum)
3087	    add_bmatchers(cc->matcher);
3088
3089	addlinknode(matchers, cc->matcher);
3090	cc->matcher->refc++;
3091    }
3092    if (mnum && (mstack || bmatchers))
3093	update_bmatchers();
3094
3095    /* Insert the prefix (compctl -P), if any. */
3096    if (cc->prefix) {
3097	int pl = 0;
3098
3099	if (*s) {
3100	    char *dp = rembslash(cc->prefix);
3101	    /* First find out how much of the prefix is already on the line. */
3102	    sd = dupstring(s);
3103	    untokenize(sd);
3104	    pl = pfxlen(dp, sd);
3105	    s += pl;
3106	    sd += pl;
3107	    offs -= pl;
3108	}
3109    }
3110    /* Does this compctl have a suffix (compctl -S)? */
3111    if (cc->suffix) {
3112	char *sdup = rembslash(cc->suffix);
3113	int sl = strlen(sdup), suffixll;
3114
3115	/* Ignore trailing spaces. */
3116	for (p = sdup + sl - 1; p >= sdup && *p == ' '; p--, sl--);
3117	p[1] = '\0';
3118
3119	if (!sd) {
3120	    sd = dupstring(s);
3121	    untokenize(sd);
3122	}
3123	/* If the suffix is already there, ignore it (and don't add *
3124	 * it again).                                               */
3125	if (*sd && (suffixll = strlen(sd)) >= sl &&
3126	    offs <= suffixll - sl && !strcmp(sdup, sd + suffixll - sl))
3127	    s[suffixll - sl] = '\0';
3128    }
3129    /* Do we have one of the special characters `~' and `=' at the beginning? */
3130    if (incompfunc || ((ic = *s) != Tilde && ic != Equals))
3131	ic = 0;
3132
3133    /* Check if we have to complete a parameter name... */
3134    if (!incompfunc && (p = check_param(s, 1, 0))) {
3135	s = p;
3136	/* And now make sure that we complete parameter names. */
3137	cc = &cc_dummy;
3138	cc_dummy.refc = 10000;
3139	cc_dummy.mask = CC_PARAMS | CC_ENVVARS;
3140    }
3141    ooffs = offs;
3142    /* If we have to ignore the word, do that. */
3143    if (cc->mask & CC_DELETE) {
3144	delit = 1;
3145	*s = '\0';
3146	offs = 0;
3147	if (isset(AUTOMENU))
3148	    usemenu = 1;
3149    }
3150
3151    /* Compute line prefix/suffix. */
3152    lpl = offs;
3153    lpre = zhalloc(lpl + 1);
3154    memcpy(lpre, s, lpl);
3155    lpre[lpl] = '\0';
3156    qlpre = quotename(lpre, NULL);
3157    lsuf = dupstring(s + offs);
3158    lsl = strlen(lsuf);
3159    qlsuf = quotename(lsuf, NULL);
3160
3161    /* First check for ~.../... */
3162    if (ic == Tilde) {
3163	for (p = lpre + lpl; p > lpre; p--)
3164	    if (*p == '/')
3165		break;
3166
3167	if (*p == '/')
3168	    ic = 0;
3169    }
3170    /* Compute real prefix/suffix. */
3171
3172    noreal = !delit;
3173    for (p = lpre; *p && *p != String && *p != Tick; p++);
3174    tt = ic && !ispar ? lpre + 1 : lpre;
3175    rpre = (*p || *lpre == Tilde || *lpre == Equals) ?
3176	(noreal = 0, getreal(tt)) :
3177	dupstring(tt);
3178    qrpre = quotename(rpre, NULL);
3179
3180    for (p = lsuf; *p && *p != String && *p != Tick; p++);
3181    rsuf = *p ? (noreal = 0, getreal(lsuf)) : dupstring(lsuf);
3182    qrsuf = quotename(rsuf, NULL);
3183
3184    /* Check if word is a pattern. */
3185
3186    for (s1 = NULL, sf1 = 0, p = rpre + (rpl = strlen(rpre)) - 1;
3187	 p >= rpre && (ispattern != 3 || !sf1);
3188	 p--)
3189	if (itok(*p) && (p > rpre || (*p != Equals && *p != Tilde)))
3190	    ispattern |= sf1 ? 1 : 2;
3191	else if (*p == '/') {
3192	    sf1++;
3193	    if (!s1)
3194		s1 = p;
3195	}
3196    rsl = strlen(rsuf);
3197    for (s2 = NULL, sf2 = t = 0, p = rsuf; *p && (!t || !sf2); p++)
3198	if (itok(*p))
3199	    t |= sf2 ? 4 : 2;
3200	else if (*p == '/') {
3201	    sf2++;
3202	    if (!s2)
3203		s2 = p;
3204	}
3205    ispattern = ispattern | t;
3206
3207    /* But if we were asked not to do glob completion, we never treat the *
3208     * thing as a pattern.                                                */
3209    if (!comppatmatch || !*comppatmatch)
3210	ispattern = 0;
3211
3212    if (ispattern) {
3213	/* The word should be treated as a pattern, so compute the matcher. */
3214	p = (char *) zhalloc(rpl + rsl + 2);
3215	strcpy(p, rpre);
3216	if (rpl && p[rpl - 1] != Star &&
3217	    (!comppatmatch || *comppatmatch == '*')) {
3218	    p[rpl] = Star;
3219	    strcpy(p + rpl + 1, rsuf);
3220	} else
3221	    strcpy(p + rpl, rsuf);
3222	patcomp = patcompile(p, 0, NULL);
3223	haspattern = 1;
3224    }
3225    if (!patcomp) {
3226	untokenize(rpre);
3227	untokenize(rsuf);
3228
3229	rpl = strlen(rpre);
3230	rsl = strlen(rsuf);
3231    }
3232    untokenize(lpre);
3233    untokenize(lsuf);
3234
3235    if (!(cc->mask & CC_DELETE))
3236	hasmatched = 1;
3237
3238    /* Handle completion of files specially (of course). */
3239
3240    if ((cc->mask & (CC_FILES | CC_DIRS | CC_COMMPATH)) || cc->glob) {
3241	/* s1 and s2 point to the last/first slash in the prefix/suffix. */
3242	if (!s1)
3243	    s1 = rpre;
3244	if (!s2)
3245	    s2 = rsuf + rsl;
3246
3247	/* Compute the path prefix/suffix. */
3248	if (*s1 != '/')
3249	    ppre = "";
3250	else
3251	    ppre = dupstrpfx(rpre, s1 - rpre + 1);
3252	psuf = dupstring(s2);
3253
3254	if (zlemetacs != wb) {
3255	    char save = zlemetaline[zlemetacs];
3256
3257	    zlemetaline[zlemetacs] = 0;
3258	    lppre = dupstring(zlemetaline + wb +
3259			      (qipre && *qipre ?
3260			       (strlen(qipre) -
3261				(*qipre == '\'' || *qipre == '\"')) : 0));
3262	    zlemetaline[zlemetacs] = save;
3263	    if (brbeg) {
3264		Brinfo bp;
3265
3266		for (bp = brbeg; bp; bp = bp->next)
3267		    strcpy(lppre + bp->qpos,
3268			   lppre + bp->qpos + strlen(bp->str));
3269	    }
3270	    if ((p = strrchr(lppre, '/'))) {
3271		p[1] = '\0';
3272		lppl = strlen(lppre);
3273	    } else if (!sf1) {
3274		lppre = NULL;
3275		lppl = 0;
3276	    } else {
3277		lppre = ppre;
3278		lppl = strlen(lppre);
3279	    }
3280	} else {
3281	    lppre = NULL;
3282	    lppl = 0;
3283	}
3284	if (zlemetacs != we) {
3285	    int end = we;
3286	    char save = zlemetaline[end];
3287
3288	    if (qisuf && *qisuf) {
3289		int ql = strlen(qisuf);
3290
3291		end -= ql - (qisuf[ql-1] == '\'' || qisuf[ql-1] == '"');
3292	    }
3293	    zlemetaline[end] = 0;
3294	    lpsuf = dupstring(zlemetaline + zlemetacs);
3295	    zlemetaline[end] = save;
3296	    if (brend) {
3297		Brinfo bp;
3298		char *p;
3299		int bl;
3300
3301		for (bp = brend; bp; bp = bp->next) {
3302		    p = lpsuf + (we - zlemetacs) - bp->qpos -
3303			(bl = strlen(bp->str));
3304		    strcpy(p, p + bl);
3305		}
3306	    }
3307	    if (!(lpsuf = strchr(lpsuf, '/')) && sf2)
3308		lpsuf = psuf;
3309	    lpsl = (lpsuf ? strlen(lpsuf) : 0);
3310	} else {
3311	    lpsuf = NULL;
3312	    lpsl = 0;
3313	}
3314
3315	/* And get the file prefix. */
3316	fpre = dupstring(((s1 == s || s1 == rpre || ic) &&
3317			  (*s != '/' || zlemetacs == wb)) ? s1 : s1 + 1);
3318	qfpre = quotename(fpre, NULL);
3319	/* And the suffix. */
3320	fsuf = dupstrpfx(rsuf, s2 - rsuf);
3321	qfsuf = quotename(fsuf, NULL);
3322
3323	if (comppatmatch && *comppatmatch && (ispattern & 2)) {
3324	    int t2;
3325
3326	    /* We have to use globbing, so compute the pattern from *
3327	     * the file prefix and suffix with a `*' between them.  */
3328	    p = (char *) zhalloc((t2 = strlen(fpre)) + strlen(fsuf) + 2);
3329	    strcpy(p, fpre);
3330	    if ((!t2 || p[t2 - 1] != Star) && *fsuf != Star &&
3331		(!comppatmatch || *comppatmatch == '*'))
3332		p[t2++] = Star;
3333	    strcpy(p + t2, fsuf);
3334	    filecomp = patcompile(p, 0, NULL);
3335	}
3336	if (!filecomp) {
3337	    untokenize(fpre);
3338	    untokenize(fsuf);
3339
3340	    fpl = strlen(fpre);
3341	    fsl = strlen(fsuf);
3342	}
3343	addwhat = -1;
3344
3345	/* Completion after `~', maketildelist adds the usernames *
3346	 * and named directories.                                 */
3347	if (ic == Tilde) {
3348	    char *oi = ipre;
3349
3350	    ipre = (ipre ? dyncat("~", ipre) : "~");
3351	    maketildelist();
3352	    ipre = oi;
3353	} else if (ic == Equals) {
3354	    /* Completion after `=', get the command names from *
3355	     * the cmdnamtab and aliases from aliastab.         */
3356	    char *oi = ipre;
3357
3358	    ipre = (ipre ? dyncat("=", ipre) : "=");
3359	    if (isset(HASHLISTALL))
3360		cmdnamtab->filltable(cmdnamtab);
3361	    dumphashtable(cmdnamtab, -7);
3362	    dumphashtable(aliastab, -2);
3363	    ipre = oi;
3364	} else {
3365	    /* Normal file completion... */
3366	    if (ispattern & 1) {
3367		/* But with pattern matching. */
3368		LinkList l = newlinklist();
3369		LinkNode n;
3370		int ng = opts[NULLGLOB];
3371
3372		opts[NULLGLOB] = 1;
3373
3374		addwhat = 0;
3375		p = (char *) zhalloc(lpl + lsl + 3);
3376		strcpy(p, lpre);
3377		if (*lsuf != '*' && *lpre && lpre[lpl - 1] != '*')
3378		    strcat(p, "*");
3379		strcat(p, lsuf);
3380		if (*lsuf && lsuf[lsl - 1] != '*' && lsuf[lsl - 1] != ')')
3381		    strcat(p, "*");
3382
3383		/* Do the globbing. */
3384		tokenize(p);
3385		remnulargs(p);
3386		addlinknode(l, p);
3387		globlist(l, 0);
3388
3389		if (nonempty(l)) {
3390		    /* And add the resulting words. */
3391		    mflags |= CMF_FILE;
3392		    for (n = firstnode(l); n; incnode(n))
3393			addmatch(getdata(n), NULL);
3394		    mflags &= !CMF_FILE;
3395		}
3396		opts[NULLGLOB] = ng;
3397	    } else {
3398		char **dirs = 0, *ta[2];
3399
3400		/* No pattern matching. */
3401		addwhat = CC_FILES;
3402
3403		if (cc->withd) {
3404		    char **pp, **npp, *tp;
3405		    int tl = strlen(ppre) + 2, pl;
3406
3407		    if ((pp = get_user_var(cc->withd))) {
3408			dirs = npp =
3409			    (char**) zhalloc(sizeof(char *)*(arrlen(pp)+1));
3410			while (*pp) {
3411			    pl = strlen(*pp);
3412			    tp = (char *) zhalloc(strlen(*pp) + tl);
3413			    strcpy(tp, *pp);
3414			    tp[pl] = '/';
3415			    strcpy(tp + pl + 1, ppre);
3416			    *npp++ = tp;
3417			    pp++;
3418			}
3419			*npp = '\0';
3420		    }
3421		}
3422		if (!dirs) {
3423		    dirs = ta;
3424		    if (cc->withd) {
3425			char *tp;
3426			int pl = strlen(cc->withd);
3427
3428			ta[0] = tp = (char *) zhalloc(strlen(ppre) + pl + 2);
3429			strcpy(tp, cc->withd);
3430			tp[pl] = '/';
3431			strcpy(tp + pl + 1, ppre);
3432		    } else
3433			ta[0] = ppre;
3434		    ta[1] = NULL;
3435		}
3436		while (*dirs) {
3437		    prpre = *dirs;
3438
3439		    if (sf2)
3440			/* We are in the path, so add only directories. */
3441			gen_matches_files(1, 0, 0);
3442		    else {
3443			if (cc->mask & CC_FILES)
3444			    /* Add all files. */
3445			    gen_matches_files(0, 0, 1);
3446			else if (cc->mask & CC_COMMPATH) {
3447			    /* Completion of command paths. */
3448			    if (sf1 || cc->withd)
3449				/* There is a path prefix, so add *
3450				 * directories and executables.   */
3451				gen_matches_files(1, 1, 0);
3452			    else {
3453				/* No path prefix, so add the things *
3454				 * reachable via the PATH variable.  */
3455				char **pc = path, *pp = prpre;
3456
3457				for (; *pc; pc++)
3458				    if (!**pc || (pc[0][0] == '.' && !pc[0][1]))
3459					break;
3460				if (*pc) {
3461				    prpre = "./";
3462				    gen_matches_files(1, 1, 0);
3463				    prpre = pp;
3464				}
3465			    }
3466			} else if (cc->mask & CC_DIRS)
3467			    gen_matches_files(1, 0, 0);
3468			/* The compctl has a glob pattern (compctl -g). */
3469			if (cc->glob) {
3470			    int ns, pl = strlen(prpre), o, paalloc;
3471			    char *g = dupstring(cc->glob), *pa;
3472			    char *p2, *p3;
3473			    int ne = noerrs, md = opts[MARKDIRS];
3474
3475			    /* These are used in the globbing code to make *
3476			     * things a bit faster.                        */
3477			    if (ispattern || mstack)
3478				glob_pre = glob_suf = NULL;
3479			    else {
3480				glob_pre = fpre;
3481				glob_suf = fsuf;
3482			    }
3483			    noerrs = 1;
3484			    addwhat = -6;
3485			    o = strlen(prpre);
3486			    pa = (char *)zalloc(paalloc = o + PATH_MAX);
3487			    strcpy(pa, prpre);
3488			    opts[MARKDIRS] = 0;
3489
3490			    /* The compctl -g string may contain more than *
3491			     * one pattern, so we need a loop.             */
3492			    while (*g) {
3493				LinkList l = newlinklist();
3494				int ng;
3495
3496				/* Find the blank terminating the pattern. */
3497				while (*g && inblank(*g))
3498				    g++;
3499				/* Oops, we already reached the end of the
3500				   string. */
3501				if (!*g)
3502				    break;
3503				for (p = g + 1; *p && !inblank(*p); p++)
3504				    if (*p == '\\' && p[1])
3505					p++;
3506				/* Get the pattern string. */
3507				tokenize(g = dupstrpfx(g, p - g));
3508				if (*g == '=' && isset(EQUALS))
3509				    *g = Equals;
3510				if (*g == '~')
3511				    *g = Tilde;
3512				remnulargs(g);
3513				if ((*g == Equals || *g == Tilde) && !cc->withd) {
3514				/* The pattern has a `~' or `=' at the  *
3515				 * beginning, so we expand this and use *
3516				 * the result.                          */
3517				    filesub(&g, 0);
3518				    addlinknode(l, dupstring(g));
3519				} else if (*g == '/' && !cc->withd)
3520				/* The pattern is a full path (starting *
3521				 * with '/'), so add it unchanged.      */
3522				    addlinknode(l, dupstring(g));
3523				else {
3524				/* It's a simple pattern, so append it to *
3525				 * the path we have on the command line.  */
3526				    int minlen = o + strlen(g);
3527				    if (minlen >= paalloc)
3528					pa = (char *)
3529					    zrealloc(pa, paalloc = minlen+1);
3530				    strcpy(pa + o, g);
3531				    addlinknode(l, dupstring(pa));
3532				}
3533				/* Do the globbing. */
3534				ng = opts[NULLGLOB];
3535				opts[NULLGLOB] = 1;
3536				globlist(l, 0);
3537				opts[NULLGLOB] = ng;
3538				/* Get the results. */
3539				if (nonempty(l) && peekfirst(l)) {
3540				    for (p2 = (char *)peekfirst(l); *p2; p2++)
3541					if (itok(*p2))
3542					    break;
3543				    if (!*p2) {
3544					if ((*g == Equals || *g == Tilde ||
3545					     *g == '/') || cc->withd) {
3546					    /* IF the pattern started with `~',  *
3547					     * `=', or `/', add the result only, *
3548					     * if it really matches what we have *
3549					     * on the line.                      *
3550					     * Do this if an initial directory   *
3551					     * was specified, too.               */
3552					    while ((p2 = (char *)ugetnode(l)))
3553						if (strpfx(prpre, p2))
3554						    addmatch(p2 + pl, NULL);
3555					} else {
3556					    /* Otherwise ignore the path we *
3557					     * prepended to the pattern.    */
3558					    while ((p2 = p3 =
3559						    (char *)ugetnode(l))) {
3560						for (ns = sf1; *p3 && ns; p3++)
3561						    if (*p3 == '/')
3562							ns--;
3563
3564						addmatch(p3, NULL);
3565					    }
3566					}
3567				    }
3568				}
3569				pa[o] = '\0';
3570				g = p;
3571			    }
3572			    glob_pre = glob_suf = NULL;
3573			    noerrs = ne;
3574			    opts[MARKDIRS] = md;
3575
3576			    zfree(pa, paalloc);
3577			}
3578		    }
3579		    dirs++;
3580		}
3581		prpre = NULL;
3582	    }
3583	}
3584	lppre = lpsuf = NULL;
3585	lppl = lpsl = 0;
3586    }
3587    if (ic) {
3588	/* Now change the `~' and `=' tokens to the real characters so *
3589	 * that things starting with these characters will be added.   */
3590	rpre = dyncat((ic == Tilde) ? "~" : "=", rpre);
3591	rpl++;
3592	qrpre = dyncat((ic == Tilde) ? "~" : "=", qrpre);
3593    }
3594    if (!ic && (cc->mask & CC_COMMPATH) && !*ppre && !*psuf) {
3595	/* If we have to complete commands, add alias names, *
3596	 * shell functions and builtins too.                 */
3597	dumphashtable(aliastab, -3);
3598	dumphashtable(reswdtab, -3);
3599	dumphashtable(shfunctab, -3);
3600	dumphashtable(builtintab, -3);
3601	if (isset(HASHLISTALL))
3602	    cmdnamtab->filltable(cmdnamtab);
3603	dumphashtable(cmdnamtab, -3);
3604	/* And parameter names if autocd and cdablevars are set. */
3605	if (isset(AUTOCD) && isset(CDABLEVARS))
3606	    dumphashtable(paramtab, -4);
3607    }
3608    oaw = addwhat = (cc->mask & CC_QUOTEFLAG) ? -2 : CC_QUOTEFLAG;
3609
3610    if (cc->mask & CC_NAMED)
3611	/* Add named directories. */
3612	dumphashtable(nameddirtab, addwhat);
3613    if (cc->mask & CC_OPTIONS)
3614	/* Add option names. */
3615	dumphashtable(optiontab, addwhat);
3616    if (cc->mask & CC_VARS) {
3617	/* And parameter names. */
3618	dumphashtable(paramtab, -9);
3619	addwhat = oaw;
3620    }
3621    if (cc->mask & CC_BINDINGS) {
3622	/* And zle function names... */
3623	dumphashtable(thingytab, CC_BINDINGS);
3624	addwhat = oaw;
3625    }
3626    if (cc->keyvar) {
3627	/* This adds things given to the compctl -k flag *
3628	 * (from a parameter or a list of words).        */
3629	char **usr = get_user_var(cc->keyvar);
3630
3631	if (usr)
3632	    while (*usr)
3633		addmatch(*usr++, NULL);
3634    }
3635    if (cc->mask & CC_USERS) {
3636	/* Add user names. */
3637	maketildelist();
3638	addwhat = oaw;
3639    }
3640    if (cc->func) {
3641	/* This handles the compctl -K flag. */
3642	Shfunc shfunc;
3643	char **r;
3644	int lv = lastval;
3645
3646	/* Get the function. */
3647	if ((shfunc = getshfunc(cc->func))) {
3648	    /* We have it, so build a argument list. */
3649	    LinkList args = newlinklist();
3650	    int osc = sfcontext;
3651
3652	    addlinknode(args, cc->func);
3653
3654	    if (delit) {
3655		p = dupstrpfx(os, ooffs);
3656		untokenize(p);
3657		addlinknode(args, p);
3658		p = dupstring(os + ooffs);
3659		untokenize(p);
3660		addlinknode(args, p);
3661	    } else {
3662		addlinknode(args, lpre);
3663		addlinknode(args, lsuf);
3664	    }
3665
3666	    /* This flag allows us to use read -l and -c. */
3667	    if (incompfunc != 1)
3668		incompctlfunc = 1;
3669	    sfcontext = SFC_COMPLETE;
3670	    /* Call the function. */
3671	    doshfunc(shfunc, args, 1);
3672	    sfcontext = osc;
3673	    incompctlfunc = 0;
3674	    /* And get the result from the reply parameter. */
3675	    if ((r = get_user_var("reply")))
3676		while (*r)
3677		    addmatch(*r++, NULL);
3678	}
3679	lastval = lv;
3680    }
3681    if (cc->mask & (CC_JOBS | CC_RUNNING | CC_STOPPED)) {
3682	/* Get job names. */
3683	int i;
3684	char *j;
3685
3686	for (i = 0; i <= maxjob; i++)
3687	    if ((jobtab[i].stat & STAT_INUSE) &&
3688		jobtab[i].procs && jobtab[i].procs->text) {
3689		int stopped = jobtab[i].stat & STAT_STOPPED;
3690
3691		j = dupstring(jobtab[i].procs->text);
3692		if ((cc->mask & CC_JOBS) ||
3693		    (stopped && (cc->mask & CC_STOPPED)) ||
3694		    (!stopped && (cc->mask & CC_RUNNING)))
3695		    addmatch(j, NULL);
3696	    }
3697    }
3698    if (cc->str) {
3699	/* Get the stuff from a compctl -s. */
3700	LinkList foo = newlinklist();
3701	LinkNode n;
3702	int first = 1, ng = opts[NULLGLOB], oowe = we, oowb = wb;
3703	int ona = noaliases;
3704	char *tmpbuf;
3705
3706	opts[NULLGLOB] = 1;
3707
3708	/* Put the string in the lexer buffer and call the lexer to *
3709	 * get the words we have to expand.                        */
3710	lexsave();
3711	lexflags = LEXFLAGS_ZLE;
3712	tmpbuf = (char *)zhalloc(strlen(cc->str) + 5);
3713	sprintf(tmpbuf, "foo %s", cc->str); /* KLUDGE! */
3714	inpush(tmpbuf, 0, NULL);
3715	strinbeg(0);
3716	noaliases = 1;
3717	do {
3718	    ctxtlex();
3719	    if (tok == ENDINPUT || tok == LEXERR)
3720		break;
3721	    if (!first && tokstr && *tokstr)
3722		addlinknode(foo, ztrdup(tokstr));
3723	    first = 0;
3724	} while (tok != ENDINPUT && tok != LEXERR);
3725	noaliases = ona;
3726	strinend();
3727	inpop();
3728	errflag = 0;
3729	lexrestore();
3730	/* Fine, now do full expansion. */
3731	prefork(foo, 0);
3732	if (!errflag) {
3733	    globlist(foo, 0);
3734	    if (!errflag)
3735		/* And add the resulting words as matches. */
3736		for (n = firstnode(foo); n; incnode(n))
3737		    addmatch(getdata(n), NULL);
3738	}
3739	opts[NULLGLOB] = ng;
3740	we = oowe;
3741	wb = oowb;
3742    }
3743    if (cc->hpat) {
3744	/* We have a pattern to take things from the history. */
3745	Patprog pprogc = NULL;
3746	char *e, *h, hpatsav;
3747	zlong i = addhistnum(curhist,-1,HIST_FOREIGN), n = cc->hnum;
3748	Histent he = gethistent(i, GETHIST_UPWARD);
3749
3750	/* Parse the pattern, if it isn't the null string. */
3751	if (*(cc->hpat)) {
3752	    char *thpat = dupstring(cc->hpat);
3753
3754	    tokenize(thpat);
3755	    pprogc = patcompile(thpat, 0, NULL);
3756	}
3757	/* n holds the number of history line we have to search. */
3758	if (!n)
3759	    n = -1;
3760
3761	/* Now search the history. */
3762	while (n-- && he) {
3763	    int iwords;
3764	    for (iwords = he->nwords - 1; iwords >= 0; iwords--) {
3765		h = he->node.nam + he->words[iwords*2];
3766		e = he->node.nam + he->words[iwords*2+1];
3767		hpatsav = *e;
3768		*e = '\0';
3769		/* We now have a word from the history, ignore it *
3770		 * if it begins with a quote or `$'.              */
3771		if (*h != '\'' && *h != '"' && *h != '`' && *h != '$' &&
3772		    (!pprogc || pattry(pprogc, h)))
3773		    /* Otherwise add it if it was matched. */
3774		    addmatch(dupstring(h), NULL);
3775		if (hpatsav)
3776		    *e = hpatsav;
3777	    }
3778	    he = up_histent(he);
3779	}
3780	freepatprog(pprogc);
3781    }
3782    if ((t = cc->mask & (CC_ARRAYS | CC_INTVARS | CC_ENVVARS | CC_SCALARS |
3783			 CC_READONLYS | CC_SPECIALS | CC_PARAMS)))
3784	/* Add various flavours of parameters. */
3785	dumphashtable(paramtab, t);
3786    if ((t = cc->mask & CC_SHFUNCS))
3787	/* Add shell functions. */
3788	dumphashtable(shfunctab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
3789    if ((t = cc->mask & CC_BUILTINS))
3790	/* Add builtins. */
3791	dumphashtable(builtintab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
3792    if ((t = cc->mask & CC_EXTCMDS)) {
3793	/* Add external commands */
3794	if (isset(HASHLISTALL))
3795	    cmdnamtab->filltable(cmdnamtab);
3796	dumphashtable(cmdnamtab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
3797    }
3798    if ((t = cc->mask & CC_RESWDS))
3799	/* Add reserved words */
3800	dumphashtable(reswdtab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
3801    if ((t = cc->mask & (CC_ALREG | CC_ALGLOB)))
3802	/* Add the two types of aliases. */
3803	dumphashtable(aliastab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS)));
3804    if (keypm && cc == &cc_dummy) {
3805	/* Add the keys of the parameter in keypm. */
3806	HashTable t = keypm->gsu.h->getfn(keypm);
3807
3808	if (t)
3809	    scanhashtable(t, 0, 0, PM_UNSET, addhnmatch, 0);
3810	keypm = NULL;
3811	cc_dummy.suffix = NULL;
3812    }
3813    if (!errflag && cc->ylist) {
3814	/* generate the user-defined display list: if anything fails, *
3815	 * we silently allow the normal completion list to be used.   */
3816	char **yaptr = NULL, *uv = NULL;
3817	Shfunc shfunc;
3818
3819	if (cc->ylist[0] == '$' || cc->ylist[0] == '(') {
3820	    /* from variable */
3821	    uv = cc->ylist + (cc->ylist[0] == '$');
3822	} else if ((shfunc = getshfunc(cc->ylist))) {
3823	    /* from function:  pass completions as arg list */
3824	    LinkList args = newlinklist();
3825	    LinkNode ln;
3826	    Cmatch m;
3827	    int osc = sfcontext;
3828
3829	    addlinknode(args, cc->ylist);
3830	    for (ln = firstnode(matches); ln; ln = nextnode(ln)) {
3831		m = (Cmatch) getdata(ln);
3832		if (m->ppre) {
3833		    char *s = (m->psuf ? m->psuf : "");
3834		    char *p = (char *) zhalloc(strlen(m->ppre) + strlen(m->str) +
3835					      strlen(s) + 1);
3836
3837		    sprintf(p, "%s%s%s", m->ppre, m->str, s);
3838		    addlinknode(args, dupstring(p));
3839		} else
3840		    addlinknode(args, dupstring(m->str));
3841	    }
3842
3843	    /* No harm in allowing read -l and -c here, too */
3844	    if (incompfunc != 1)
3845		incompctlfunc = 1;
3846	    sfcontext = SFC_COMPLETE;
3847	    doshfunc(shfunc, args, 1);
3848	    sfcontext = osc;
3849	    incompctlfunc = 0;
3850	    uv = "reply";
3851	}
3852	if (uv)
3853	    yaptr = get_user_var(uv);
3854	if ((tt = cc->explain)) {
3855	    tt = dupstring(tt);
3856	    if ((cc->mask & CC_EXPANDEXPL) && !parsestr(tt)) {
3857		singsub(&tt);
3858		untokenize(tt);
3859	    }
3860	    curexpl->str = tt;
3861	    if (cc->gname) {
3862		endcmgroup(yaptr);
3863		begcmgroup(cc->gname, gflags);
3864		addexpl(0);
3865	    } else {
3866		addexpl(0);
3867		endcmgroup(yaptr);
3868		begcmgroup("default", 0);
3869	    }
3870	} else {
3871	    endcmgroup(yaptr);
3872	    begcmgroup("default", 0);
3873	}
3874    } else if ((tt = cc->explain)) {
3875	tt = dupstring(tt);
3876	if ((cc->mask & CC_EXPANDEXPL) && !parsestr(tt)) {
3877	    singsub(&tt);
3878	    untokenize(tt);
3879	}
3880	curexpl->str = tt;
3881	addexpl(0);
3882    }
3883    if (cc->subcmd) {
3884	/* Handle -l sub-completion. */
3885	char **ow = clwords, *os = cmdstr, *ops = NULL;
3886	int oldn = clwnum, oldp = clwpos, br;
3887	unsigned long occ = ccont;
3888
3889	ccont = CC_CCCONT;
3890
3891	/* So we restrict the words-array. */
3892	if (brange >= clwnum)
3893	    brange = clwnum - 1;
3894	if (brange < 1)
3895	    brange = 1;
3896	if (erange >= clwnum)
3897	    erange = clwnum - 1;
3898	if (erange < 1)
3899	    erange = 1;
3900	clwnum = erange - brange + 1;
3901	clwpos = clwpos - brange;
3902	br = brange;
3903
3904	if (cc->subcmd[0]) {
3905	    /* And probably put the command name given to the flag *
3906	     * in the array.                                       */
3907	    clwpos++;
3908	    clwnum++;
3909	    incmd = 0;
3910	    ops = clwords[br - 1];
3911	    clwords[br - 1] = ztrdup(cc->subcmd);
3912	    cmdstr = ztrdup(cc->subcmd);
3913	    clwords += br - 1;
3914	} else {
3915	    cmdstr = ztrdup(clwords[br]);
3916	    incmd = !clwpos;
3917	    clwords += br;
3918	}
3919	/* Produce the matches. */
3920	makecomplistcmd(s, incmd, CFN_FIRST);
3921
3922	/* And restore the things we changed. */
3923	clwords = ow;
3924	zsfree(cmdstr);
3925	cmdstr = os;
3926	clwnum = oldn;
3927	clwpos = oldp;
3928	if (ops) {
3929	    zsfree(clwords[br - 1]);
3930	    clwords[br - 1] = ops;
3931	}
3932	ccont = occ;
3933    }
3934    if (cc->substr)
3935	sep_comp_string(cc->substr, s, offs);
3936    uremnode(ccstack, firstnode(ccstack));
3937    if (cc->matcher)
3938	mstack = mstack->next;
3939
3940    if (mn == mnum)
3941	haspattern = ohp;
3942}
3943
3944
3945static struct builtin bintab[] = {
3946    BUILTIN("compcall", 0, bin_compcall, 0, 0, 0, "TD", NULL),
3947    BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL),
3948};
3949
3950static struct features module_features = {
3951    bintab, sizeof(bintab)/sizeof(*bintab),
3952    NULL, 0,
3953    NULL, 0,
3954    NULL, 0,
3955    0
3956};
3957
3958/**/
3959int
3960setup_(UNUSED(Module m))
3961{
3962    compctlreadptr = compctlread;
3963    createcompctltable();
3964    cc_compos.mask = CC_COMMPATH;
3965    cc_compos.mask2 = 0;
3966    cc_default.refc = 10000;
3967    cc_default.mask = CC_FILES;
3968    cc_default.mask2 = 0;
3969    cc_first.refc = 10000;
3970    cc_first.mask = 0;
3971    cc_first.mask2 = CC_CCCONT;
3972
3973    lastccused = NULL;
3974
3975    return 0;
3976}
3977
3978/**/
3979int
3980features_(Module m, char ***features)
3981{
3982    *features = featuresarray(m, &module_features);
3983    return 0;
3984}
3985
3986/**/
3987int
3988enables_(Module m, int **enables)
3989{
3990    return handlefeatures(m, &module_features, enables);
3991}
3992
3993/**/
3994int
3995boot_(Module m)
3996{
3997    addhookfunc("compctl_make", (Hookfn) ccmakehookfn);
3998    addhookfunc("compctl_cleanup", (Hookfn) cccleanuphookfn);
3999    return 0;
4000}
4001
4002/**/
4003int
4004cleanup_(Module m)
4005{
4006    deletehookfunc("compctl_make", (Hookfn) ccmakehookfn);
4007    deletehookfunc("compctl_cleanup", (Hookfn) cccleanuphookfn);
4008    return setfeatureenables(m, &module_features, NULL);
4009}
4010
4011/**/
4012int
4013finish_(UNUSED(Module m))
4014{
4015    deletehashtable(compctltab);
4016
4017    if (lastccused)
4018	freelinklist(lastccused, (FreeFunc) freecompctl);
4019
4020    compctlreadptr = fallback_compctlread;
4021    return 0;
4022}
4023