1/*
2 * computil.c - completion utilities
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1999 Sven Wischnowsky
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 Sven Wischnowsky 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 Sven Wischnowsky and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Sven Wischnowsky 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 Sven Wischnowsky and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30#include "computil.mdh"
31#include "computil.pro"
32
33
34/* Help for `_describe'. */
35
36typedef struct cdset *Cdset;
37typedef struct cdstr *Cdstr;
38typedef struct cdrun *Cdrun;
39
40struct cdstate {
41    int showd;			/* != 0 if descriptions should be shown */
42    char *sep;			/* the separator string */
43    int slen;			/* its metafied length */
44    int swidth;			/* its screen width */
45    int maxmlen;                /* maximum length to allow for the matches */
46    Cdset sets;			/* the sets of matches */
47    int pre;                    /* longest prefix length (before description) */
48    int premaxw;		/* ... and its screen width */
49    int suf;                    /* longest suffix (description) */
50    int maxg;                   /* size of largest group */
51    int maxglen;                /* columns for matches of largest group */
52    int groups;                 /* number of groups */
53    int descs;                  /* number of non-group matches with desc */
54    int gprew;                   /* prefix screen width for group display */
55    Cdrun runs;                 /* runs to report to shell code */
56};
57
58struct cdstr {
59    Cdstr next;                 /* the next one in this set */
60    char *str;                  /* the string to display */
61    char *desc;                 /* the description or NULL */
62    char *match;                /* the match to add */
63    char *sortstr;		/* unmetafied string used to sort matches */
64    int len;                    /* length of str or match */
65    int width;			/* ... and its screen width */
66    Cdstr other;                /* next string with the same description */
67    int kind;                   /* 0: not in a group, 1: the first, 2: other */
68    Cdset set;                  /* the set this string is in */
69    Cdstr run;                  /* next in this run */
70};
71
72struct cdrun {
73    Cdrun next;                 /* ... */
74    int type;                   /* see CRT_* below */
75    Cdstr strs;                 /* strings in this run */
76    int count;                  /* number of strings in this run */
77};
78
79#define CRT_SIMPLE 0
80#define CRT_DESC   1
81#define CRT_SPEC   2
82#define CRT_DUMMY  3
83#define CRT_EXPL   4
84
85struct cdset {
86    Cdset next;			/* guess what */
87    char **opts;		/* the compadd-options */
88    Cdstr strs;                 /* the strings/matches */
89    int count;                  /* number of matches in this set */
90    int desc;                   /* number of matches with description */
91};
92
93static struct cdstate cd_state;
94static int cd_parsed = 0;
95
96static void
97freecdsets(Cdset p)
98{
99    Cdset n;
100    Cdstr s, sn;
101    Cdrun r, rn;
102
103    for (; p; p = n) {
104	n = p->next;
105	if (p->opts)
106	    freearray(p->opts);
107        for (s = p->strs; s; s = sn) {
108            sn = s->next;
109	    zfree(s->sortstr, strlen(s->str) + 1);
110            zsfree(s->str);
111            zsfree(s->desc);
112            if (s->match != s->str)
113                zsfree(s->match);
114            zfree(s, sizeof(*s));
115        }
116        for (r = cd_state.runs; r; r = rn) {
117            rn = r->next;
118            zfree(r, sizeof(*r));
119        }
120	zfree(p, sizeof(*p));
121    }
122}
123
124/* Find matches with same descriptions and group them. */
125
126static void
127cd_group(int maxg)
128{
129    Cdset set1, set2;
130    Cdstr str1, str2, *strp;
131    int num, width;
132
133    cd_state.groups = cd_state.descs = cd_state.maxglen = 0;
134    cd_state.maxg = 0;
135
136    for (set1 = cd_state.sets; set1; set1 = set1->next)
137        for (str1 = set1->strs; str1; str1 = str1->next) {
138            str1->kind = 0;
139            str1->other = NULL;
140        }
141
142    for (set1 = cd_state.sets; set1; set1 = set1->next) {
143        for (str1 = set1->strs; str1; str1 = str1->next) {
144            if (!str1->desc || str1->kind != 0)
145                continue;
146
147            num = 1;
148            width = str1->width + cd_state.swidth;
149            if (width > cd_state.maxglen)
150                cd_state.maxglen = width;
151            strp = &(str1->other);
152
153            for (set2 = set1; set2; set2 = set2->next) {
154                for (str2 = (set2 == set1 ? str1->next : set2->strs);
155                     str2; str2 = str2->next)
156                    if (str2->desc && !strcmp(str1->desc, str2->desc)) {
157                        width += CM_SPACE + str2->width;
158                        if (width > cd_state.maxmlen || num == maxg)
159                            break;
160                        if (width > cd_state.maxglen)
161                            cd_state.maxglen = width;
162                        str1->kind = 1;
163                        str2->kind = 2;
164                        num++;
165                        *strp = str2;
166                        strp = &(str2->other);
167                    }
168                if (str2)
169                    break;
170            }
171            *strp = NULL;
172
173            if (num > 1)
174                cd_state.groups++;
175            else
176                cd_state.descs++;
177
178            if (num > cd_state.maxg)
179                cd_state.maxg = num;
180        }
181    }
182}
183
184/* Calculate longest prefix and suffix and count the strings with
185 * descriptions. */
186
187static void
188cd_calc()
189{
190    Cdset set;
191    Cdstr str;
192    int l;
193
194    cd_state.pre = cd_state.suf = 0;
195
196    for (set = cd_state.sets; set; set = set->next) {
197        set->count = set->desc = 0;
198        for (str = set->strs; str; str = str->next) {
199            set->count++;
200            if ((l = strlen(str->str)) > cd_state.pre)
201                cd_state.pre = l;
202            if ((l = MB_METASTRWIDTH(str->str)) > cd_state.premaxw)
203                cd_state.premaxw = l;
204            if (str->desc) {
205                set->desc++;
206                if ((l = strlen(str->desc)) > cd_state.suf)
207                    cd_state.suf = l;
208            }
209        }
210    }
211}
212
213static int
214cd_sort(const void *a, const void *b)
215{
216    return zstrcmp((*((Cdstr *) a))->sortstr, (*((Cdstr *) b))->sortstr, 0);
217}
218
219static int
220cd_prep()
221{
222    Cdrun run, *runp;
223    Cdset set;
224    Cdstr str, *strp;
225
226    runp = &(cd_state.runs);
227
228    if (cd_state.groups) {
229        int preplines = cd_state.groups + cd_state.descs;
230        VARARR(Cdstr, grps, preplines);
231        VARARR(int, wids, cd_state.maxg);
232        Cdstr gs, gp, gn, *gpp;
233        int i, j, d;
234        Cdrun expl;
235        Cdstr *strp2;
236
237        memset(wids, 0, cd_state.maxg * sizeof(int));
238        strp = grps;
239
240        for (set = cd_state.sets; set; set = set->next)
241            for (str = set->strs; str; str = str->next) {
242                if (str->kind != 1) {
243                    if (!str->kind && str->desc) {
244                        if (str->width > wids[0])
245                            wids[0] = str->width;
246                        str->other = NULL;
247                        *strp++ = str;
248                    }
249                    continue;
250                }
251                gs = str;
252                gs->kind = 2;
253                gp = str->other;
254                gs->other = NULL;
255                for (; gp; gp = gn) {
256                    gn = gp->other;
257                    gp->other = NULL;
258                    for (gpp = &gs; *gpp && (*gpp)->width > gp->width;
259                         gpp = &((*gpp)->other));
260                    gp->other = *gpp;
261                    *gpp = gp;
262                }
263                for (gp = gs, i = 0; gp; gp = gp->other, i++)
264                    if (gp->width > wids[i])
265                        wids[i] = gp->width;
266
267                *strp++ = gs;
268            }
269
270        cd_state.gprew = 0;
271        for (i = 0; i < cd_state.maxg; i++) {
272            cd_state.gprew += wids[i] + CM_SPACE;
273	}
274
275        if (cd_state.gprew > cd_state.maxmlen && cd_state.maxglen > 1)
276            return 1;
277
278	for (i = 0; i < preplines; i++) {
279	    Cdstr s = grps[i];
280	    int dummy;
281
282	    s->sortstr = ztrdup(s->str);
283	    unmetafy(s->sortstr, &dummy);
284	}
285
286        qsort(grps, preplines, sizeof(Cdstr), cd_sort);
287
288        for (i = preplines, strp = grps; i > 1; i--, strp++) {
289            strp2 = strp + 1;
290            if (!strcmp((*strp)->desc, (*strp2)->desc))
291                continue;
292            for (j = i - 2, strp2++; j > 0; j--, strp2++)
293                if (!strcmp((*strp)->desc, (*strp2)->desc)) {
294                    Cdstr tmp = *strp2;
295
296                    memmove(strp + 2, strp + 1,
297                            (strp2 - strp - 1) * sizeof(Cdstr));
298
299                    *++strp = tmp;
300                    i--;
301                }
302        }
303        expl =  (Cdrun) zalloc(sizeof(*run));
304        expl->type = CRT_EXPL;
305        expl->strs = grps[0];
306        expl->count = preplines;
307
308        for (i = preplines, strp = grps, strp2 = NULL; i; i--, strp++) {
309            str = *strp;
310            *strp = str->other;
311            if (strp2)
312                *strp2 = str;
313            strp2 = &(str->run);
314
315            *runp = run = (Cdrun) zalloc(sizeof(*run));
316            runp = &(run->next);
317            run->type = CRT_SPEC;
318            run->strs = str;
319            run->count = 1;
320        }
321        *strp2 = NULL;
322
323        for (i = cd_state.maxg - 1; i; i--) {
324            for (d = 0, j = preplines, strp = grps; j; j--, strp++) {
325                if ((str = *strp)) {
326                    if (d) {
327                        *runp = run = (Cdrun) zalloc(sizeof(*run));
328                        runp = &(run->next);
329                        run->type = CRT_DUMMY;
330                        run->strs = expl->strs;
331                        run->count = d;
332                        d = 0;
333                    }
334                    *runp = run = (Cdrun) zalloc(sizeof(*run));
335                    runp = &(run->next);
336                    run->type = CRT_SPEC;
337                    run->strs = str;
338                    run->strs->run = NULL;
339                    run->count = 1;
340
341                    *strp = str->other;
342                } else
343                    d++;
344            }
345            if (d) {
346                *runp = run = (Cdrun) zalloc(sizeof(*run));
347                runp = &(run->next);
348                run->type = CRT_DUMMY;
349                run->strs = expl->strs;
350                run->count = d;
351            }
352        }
353        *runp = expl;
354        runp = &(expl->next);
355
356        for (set = cd_state.sets; set; set = set->next) {
357            for (i = 0, gs = NULL, gpp = &gs, str = set->strs;
358                 str; str = str->next) {
359                if (str->kind || str->desc)
360                    continue;
361
362                i++;
363                *gpp = str;
364                gpp = &(str->run);
365            }
366            *gpp = NULL;
367            if (i) {
368                *runp = run = (Cdrun) zalloc(sizeof(*run));
369                runp = &(run->next);
370                run->type = CRT_SIMPLE;
371                run->strs = gs;
372                run->count = i;
373            }
374        }
375    } else if (cd_state.showd) {
376        for (set = cd_state.sets; set; set = set->next) {
377            if (set->desc) {
378                *runp = run = (Cdrun) zalloc(sizeof(*run));
379                runp = &(run->next);
380                run->type = CRT_DESC;
381                strp = &(run->strs);
382                for (str = set->strs; str; str = str->next)
383                    if (str->desc) {
384                        *strp = str;
385                        strp = &(str->run);
386                    }
387                *strp = NULL;
388                run->count = set->desc;
389            }
390            if (set->desc != set->count) {
391                *runp = run = (Cdrun) zalloc(sizeof(*run));
392                runp = &(run->next);
393                run->type = CRT_SIMPLE;
394                strp = &(run->strs);
395                for (str = set->strs; str; str = str->next)
396                    if (!str->desc) {
397                        *strp = str;
398                        strp = &(str->run);
399                    }
400                *strp = NULL;
401                run->count = set->count - set->desc;
402            }
403        }
404    } else {
405        for (set = cd_state.sets; set; set = set->next)
406            if (set->count) {
407                *runp = run = (Cdrun) zalloc(sizeof(*run));
408                runp = &(run->next);
409                run->type = CRT_SIMPLE;
410                run->strs = set->strs;
411                for (str = set->strs; str; str = str->next)
412                    str->run = str->next;
413                run->count = set->count;
414            }
415    }
416    *runp = NULL;
417
418    return 0;
419}
420
421/* Duplicate and concatenate two arrays.  Return the result. */
422
423static char **
424cd_arrcat(char **a, char **b)
425{
426    if (!b)
427        return zarrdup(a);
428    else {
429        char **r = (char **) zalloc((arrlen(a) + arrlen(b) + 1) *
430                                    sizeof(char *));
431        char **p = r;
432
433        for (; *a; a++)
434            *p++ = ztrdup(*a);
435        for (; *b; b++)
436            *p++ = ztrdup(*b);
437
438        *p = NULL;
439
440        return r;
441    }
442}
443
444/* Initialisation. Store and calculate the string and matches and so on. */
445
446static int
447cd_init(char *nam, char *hide, char *mlen, char *sep,
448        char **opts, char **args, int disp)
449{
450    Cdset *setp, set;
451    Cdstr *strp, str;
452    char **ap, *tmp;
453    int grp = 0, itmp;
454
455    if (cd_parsed) {
456	zsfree(cd_state.sep);
457	freecdsets(cd_state.sets);
458	cd_parsed = 0;
459    }
460    setp = &(cd_state.sets);
461    cd_state.sep = ztrdup(sep);
462    cd_state.slen = strlen(sep);
463    cd_state.swidth = MB_METASTRWIDTH(sep);
464    cd_state.sets = NULL;
465    cd_state.showd = disp;
466    cd_state.maxg = cd_state.groups = cd_state.descs = 0;
467    cd_state.maxmlen = atoi(mlen);
468    cd_state.premaxw = 0;
469    itmp = zterm_columns - cd_state.swidth - 4;
470    if (cd_state.maxmlen > itmp)
471        cd_state.maxmlen = itmp;
472    if (cd_state.maxmlen < 4)
473        cd_state.maxmlen = 4;
474    if (*args && !strcmp(*args, "-g")) {
475        args++;
476        grp = 1;
477    }
478    while (*args) {
479	*setp = set = (Cdset) zshcalloc(sizeof(*set));
480	setp = &(set->next);
481        *setp = NULL;
482        set->opts = NULL;
483        set->strs = NULL;
484
485	if (!(ap = get_user_var(*args))) {
486	    zwarnnam(nam, "invalid argument: %s", *args);
487            zsfree(cd_state.sep);
488            freecdsets(cd_state.sets);
489	    return 1;
490	}
491        for (str = NULL, strp = &(set->strs); *ap; ap++) {
492            *strp = str = (Cdstr) zalloc(sizeof(*str));
493            strp = &(str->next);
494
495            str->kind = 0;
496            str->other = NULL;
497            str->set = set;
498
499            for (tmp = *ap; *tmp && *tmp != ':'; tmp++)
500                if (*tmp == '\\' && tmp[1])
501                    tmp++;
502
503            if (*tmp)
504                str->desc = ztrdup(rembslash(tmp + 1));
505            else
506                str->desc = NULL;
507            *tmp = '\0';
508            str->str = str->match = ztrdup(rembslash(*ap));
509            str->len = strlen(str->str);
510            str->width = MB_METASTRWIDTH(str->str);
511	    str->sortstr = NULL;
512        }
513        if (str)
514            str->next = NULL;
515
516	if (*++args && **args != '-') {
517	    if (!(ap = get_user_var(*args))) {
518		zwarnnam(nam, "invalid argument: %s", *args);
519                zsfree(cd_state.sep);
520                freecdsets(cd_state.sets);
521		return 1;
522	    }
523            for (str = set->strs; str && *ap; str = str->next, ap++)
524                str->match = ztrdup(*ap);
525
526	    args++;
527	}
528        if (hide && *hide) {
529            for (str = set->strs; str; str = str->next) {
530                if (str->str == str->match)
531                    str->str = ztrdup(str->str);
532                if (hide[1] && str->str[0] == '-' && str->str[1] == '-')
533                    strcpy(str->str, str->str + 2);
534                else if (str->str[0] == '-' || str->str[0] == '+')
535                    strcpy(str->str, str->str + 1);
536            }
537        }
538	for (ap = args; *args &&
539		 (args[0][0] != '-' || args[0][1] != '-' || args[0][2]);
540	     args++);
541
542	tmp = *args;
543	*args = NULL;
544	set->opts = cd_arrcat(ap, opts);
545	if ((*args = tmp))
546	    args++;
547    }
548    if (disp && grp) {
549        int mg = zterm_columns;
550
551        do {
552            cd_group(mg);
553            mg = cd_state.maxg - 1;
554            cd_calc();
555        } while (cd_prep());
556
557    } else {
558        cd_calc();
559        cd_prep();
560    }
561    cd_parsed = 1;
562    return 0;
563}
564
565/* Copy an array with one element in reserve (at the beginning). */
566
567static char **
568cd_arrdup(char **a)
569{
570    char **r = (char **) zalloc((arrlen(a) + 2) * sizeof(char *));
571    char **p = r + 1;
572
573    while (*a)
574        *p++ = ztrdup(*a++);
575    *p = NULL;
576
577    return r;
578}
579
580/* Get the next set. */
581
582static int
583cd_get(char **params)
584{
585    Cdrun run;
586
587    if ((run = cd_state.runs)) {
588        Cdstr str;
589        char **mats, **mp, **dpys, **dp, **opts, *csl = "";
590
591        cd_state.runs = run->next;
592
593        switch (run->type) {
594        case CRT_SIMPLE:
595            mats = mp = (char **) zalloc((run->count + 1) * sizeof(char *));
596            dpys = dp = (char **) zalloc((run->count + 1) * sizeof(char *));
597
598            for (str = run->strs; str; str = str->run) {
599                *mp++ = ztrdup(str->match);
600                *dp++ = ztrdup(str->str ? str->str : str->match);
601            }
602            *mp = *dp = NULL;
603            opts = zarrdup(run->strs->set->opts);
604            if (cd_state.groups) {
605                /* We are building a columnised list with dummy matches
606                 * but there are also matches without descriptions.
607                 * Those end up in a different group, so make sure that
608                 * group doesn't have an explanation. */
609
610                for (mp = dp = opts; *mp; mp++) {
611                    if (dp[0][0] == '-' && dp[0][1] == 'X') {
612                        if (!dp[0][2] && dp[1])
613                            mp++;
614                    } else
615                        *dp++ = *mp;
616                }
617                *dp = NULL;
618            }
619            break;
620
621        case CRT_DESC:
622            {
623		/*
624		 * The buffer size:
625		 *     max prefix length (cd_state.pre) +
626		 *     max padding (cd_state.premaxw generously :) +
627		 *     separator length (cd_state.slen) +
628		 *     inter matches gap (CM_SPACE) +
629		 *     max description length (cd_state.suf) +
630		 *     trailing \0
631		 */
632                VARARR(char, buf,
633                       cd_state.pre + cd_state.suf +
634		       cd_state.premaxw + cd_state.slen + 3);
635                mats = mp = (char **) zalloc((run->count + 1) * sizeof(char *));
636                dpys = dp = (char **) zalloc((run->count + 1) * sizeof(char *));
637
638                for (str = run->strs; str; str = str->run) {
639		    char *p = buf, *pp, *d;
640		    int l, remw, w;
641
642                    *mp++ = ztrdup(str->match);
643		    strcpy(p, str->str);
644		    p += str->len;
645                    memset(p, ' ', (l = (cd_state.premaxw - str->width + CM_SPACE)));
646		    p += l;
647
648		    remw = zterm_columns - cd_state.premaxw -
649			cd_state.swidth - 3;
650		    while (remw < 0 && zterm_columns) {
651			/* line wrapped, use remainder of the extra line */
652			remw += zterm_columns;
653		    }
654		    if (cd_state.slen < remw) {
655			strcpy(p, cd_state.sep);
656			p += cd_state.slen;
657			remw -= cd_state.slen;
658
659			/*
660			 * copy a character at once until no more screen
661			 * width is available. Leave 1 character at the
662			 * end of screen as safety margin
663			 */
664			d = str->desc;
665			w = MB_METASTRWIDTH(d);
666			if (w <= remw)
667			    strcpy(p, d);
668			else {
669			    pp = p;
670			    while (remw > 0 && *d) {
671				l = MB_METACHARLEN(d);
672				memcpy(pp, d, l);
673				pp[l] = '\0';
674				w = MB_METASTRWIDTH(pp);
675				if (w > remw) {
676				    *pp = '\0';
677				    break;
678				}
679
680				pp += l;
681				d += l;
682				remw -= w;
683			    }
684			}
685		    }
686
687                    *dp++ = ztrdup(buf);
688                }
689                *mp = *dp = NULL;
690                opts = cd_arrdup(run->strs->set->opts);
691                opts[0] = ztrdup("-l");
692                break;
693            }
694
695        case CRT_SPEC:
696            mats = (char **) zalloc(2 * sizeof(char *));
697            dpys = (char **) zalloc(2 * sizeof(char *));
698            mats[0] = ztrdup(run->strs->match);
699            dpys[0] = ztrdup(run->strs->str);
700            mats[1] = dpys[1] = NULL;
701            opts = cd_arrdup(run->strs->set->opts);
702            for (dp = opts + 1; *dp; dp++)
703                if (dp[0][0] == '-' && dp[0][1] == 'J')
704                    break;
705            if (*dp) {
706                char *s = tricat("-2V", "", dp[0] + 2);
707
708                zsfree(*dp);
709                *dp = s;
710
711                memmove(opts, opts + 1,
712                        (arrlen(opts + 1) + 1) * sizeof(char *));
713
714            } else
715                opts[0] = ztrdup("-2V-default-");
716            csl = "packed";
717            break;
718
719        case CRT_DUMMY:
720            {
721                char buf[20];
722
723                sprintf(buf, "-E%d", run->count);
724
725                mats = (char **) zalloc(sizeof(char *));
726                dpys = (char **) zalloc(sizeof(char *));
727                mats[0] = dpys[0] = NULL;
728
729                opts = cd_arrdup(run->strs->set->opts);
730                opts[0] = ztrdup(buf);
731
732                csl = "packed";
733            }
734            break;
735
736	default: /* This silences the "might be used uninitialized" warnings */
737        case CRT_EXPL:
738            {
739		/* add columns as safety margin */
740                VARARR(char, dbuf, cd_state.suf + cd_state.slen +
741		       zterm_columns);
742                char buf[20], *p, *pp, *d;
743                int i = run->count, remw, w, l;
744
745                sprintf(buf, "-E%d", i);
746
747                mats = (char **) zalloc(sizeof(char *));
748                dpys = (char **) zalloc((i + 1) * sizeof(char *));
749
750                for (dp = dpys, str = run->strs; str; str = str->run) {
751                    if (str->run && !strcmp(str->desc, str->run->desc)) {
752                        *dp++ = ztrdup("");
753                        continue;
754                    }
755
756                    strcpy(dbuf, cd_state.sep);
757		    remw = zterm_columns - cd_state.gprew -
758			cd_state.swidth - CM_SPACE;
759		    p = pp = dbuf + cd_state.slen;
760		    d = str->desc;
761		    w = MB_METASTRWIDTH(d);
762		    if (w <= remw) {
763			strcpy(p, d);
764			remw -= w;
765			pp += strlen(d);
766		    } else
767			while (remw > 0 && *d) {
768			    l = MB_METACHARLEN(d);
769			    memcpy(pp, d, l);
770			    pp[l] = '\0';
771			    w = MB_METASTRWIDTH(pp);
772			    if (w > remw) {
773				*pp = '\0';
774				break;
775			    }
776
777			    pp += l;
778			    d += l;
779			    remw -= w;
780			}
781
782		    while (remw-- > 0)
783			*pp++ = ' ';
784		    *pp = '\0';
785
786                    *dp++ = ztrdup(dbuf);
787                }
788                mats[0] = *dp = NULL;
789
790                opts = cd_arrdup(run->strs->set->opts);
791                opts[0] = ztrdup(buf);
792
793                csl = "packed";
794            }
795            break;
796        }
797        setsparam(params[0], ztrdup(csl));
798        setaparam(params[1], opts);
799        setaparam(params[2], mats);
800        setaparam(params[3], dpys);
801
802        zfree(run, sizeof(*run));
803
804        return 0;
805    }
806    return 1;
807}
808
809/**/
810static int
811bin_compdescribe(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
812{
813    int n = arrlen(args);
814
815    if (incompfunc != 1) {
816	zwarnnam(nam, "can only be called from completion function");
817	return 1;
818    }
819    if (!args[0][0] || !args[0][1] || args[0][2]) {
820	zwarnnam(nam, "invalid argument: %s", args[0]);
821	return 1;
822    }
823    switch (args[0][1]) {
824    case 'i':
825        if (n < 3) {
826            zwarnnam(nam, "not enough arguments");
827
828            return 1;
829        }
830	return cd_init(nam, args[1], args[2], "", NULL, args + 3, 0);
831    case 'I':
832        if (n < 6) {
833            zwarnnam(nam, "not enough arguments");
834
835            return 1;
836        } else {
837            char **opts;
838
839            if (!(opts = getaparam(args[4]))) {
840		zwarnnam(nam, "unknown parameter: %s", args[4]);
841		return 1;
842            }
843            return cd_init(nam, args[1], args[2], args[3], opts, args + 5, 1);
844        }
845    case 'g':
846	if (cd_parsed) {
847	    if (n != 5) {
848		zwarnnam(nam, (n < 5 ? "not enough arguments" :
849			      "too many arguments"));
850		return 1;
851	    }
852	    return cd_get(args + 1);
853	} else {
854	    zwarnnam(nam, "no parsed state");
855	    return 1;
856	}
857    }
858    zwarnnam(nam, "invalid option: %s", args[0]);
859    return 1;
860}
861
862/* Help for `_arguments'. */
863
864typedef struct cadef *Cadef;
865typedef struct caopt *Caopt;
866typedef struct caarg *Caarg;
867
868/* Cache for a set of _arguments-definitions. */
869
870struct cadef {
871    Cadef next;			/* next in cache */
872    Cadef snext;		/* next set */
873    Caopt opts;			/* the options */
874    int nopts, ndopts, nodopts;	/* number of options/direct/optional direct */
875    Caarg args;			/* the normal arguments */
876    Caarg rest;			/* the rest-argument */
877    char **defs;		/* the original strings */
878    int ndefs;			/* number of ... */
879    int lastt;			/* last time this was used */
880    Caopt *single;		/* array of single-letter options */
881    char *match;		/* -M spec to use */
882    int argsactive;		/* if arguments are still allowed */
883				/* used while parsing a command line */
884    char *set;			/* set name prefix (<name>-), shared */
885    char *sname;		/* set name */
886    int flags;			/* see CDF_* below */
887    char *nonarg;		/* pattern for non-args (-A argument) */
888};
889
890#define CDF_SEP 1
891
892/* Description for an option. */
893
894struct caopt {
895    Caopt next;
896    char *name;			/* option name */
897    char *descr;		/* the description */
898    char **xor;			/* if this, then not ... */
899    int type;			/* type, CAO_* */
900    Caarg args;			/* option arguments */
901    int active;			/* still allowed on command line */
902    int num;			/* it's the num'th option */
903    char *set;			/* set name, shared */
904    int not;			/* don't complete this option (`!...') */
905};
906
907#define CAO_NEXT    1
908#define CAO_DIRECT  2
909#define CAO_ODIRECT 3
910#define CAO_EQUAL   4
911#define CAO_OEQUAL  5
912
913/* Description for an argument */
914
915struct caarg {
916    Caarg next;
917    char *descr;		/* description */
918    char **xor;			/* if this, then not ... */
919    char *action;		/* what to do for it */
920    int type;			/* CAA_* below */
921    char *end;			/* end-pattern for ::<pat>:... */
922    char *opt;			/* option name if for an option */
923    int num;			/* it's the num'th argument */
924    int min;			/* it's also this argument, using opt. args */
925    int direct;			/* number was given directly */
926    int active;			/* still allowed on command line */
927    char *set;			/* set name, shared */
928};
929
930#define CAA_NORMAL 1
931#define CAA_OPT    2
932#define CAA_REST   3
933#define CAA_RARGS  4
934#define CAA_RREST  5
935
936/* The cache of parsed descriptons. */
937
938#define MAX_CACACHE 8
939static Cadef cadef_cache[MAX_CACACHE];
940
941/* Compare two arrays of strings for equality. */
942
943static int
944arrcmp(char **a, char **b)
945{
946    if (!a && !b)
947	return 1;
948    else if (!a || !b)
949	return 0;
950    else {
951	while (*a && *b)
952	    if (strcmp(*a++, *b++))
953		return 0;
954
955	return (!*a && !*b);
956    }
957}
958
959/* Memory stuff. Obviously. */
960
961static void
962freecaargs(Caarg a)
963{
964    Caarg n;
965
966    for (; a; a = n) {
967	n = a->next;
968	zsfree(a->descr);
969	if (a->xor)
970	    freearray(a->xor);
971	zsfree(a->action);
972	zsfree(a->end);
973	zsfree(a->opt);
974	zfree(a, sizeof(*a));
975    }
976}
977
978static void
979freecadef(Cadef d)
980{
981    Cadef s;
982    Caopt p, n;
983
984    while (d) {
985	s = d->snext;
986	zsfree(d->match);
987	zsfree(d->set);
988	zsfree(d->sname);
989	if (d->defs)
990	    freearray(d->defs);
991
992	for (p = d->opts; p; p = n) {
993	    n = p->next;
994	    zsfree(p->name);
995	    zsfree(p->descr);
996	    if (p->xor)
997		freearray(p->xor);
998	    freecaargs(p->args);
999	    zfree(p, sizeof(*p));
1000	}
1001	freecaargs(d->args);
1002	freecaargs(d->rest);
1003	zsfree(d->nonarg);
1004	if (d->single)
1005	    zfree(d->single, 256 * sizeof(Caopt));
1006	zfree(d, sizeof(*d));
1007	d = s;
1008    }
1009}
1010
1011/* Remove backslashes before colons. */
1012
1013static char *
1014rembslashcolon(char *s)
1015{
1016    char *p, *r;
1017
1018    r = p = s = dupstring(s);
1019
1020    while (*s) {
1021	if (s[0] != '\\' || s[1] != ':')
1022	    *p++ = *s;
1023	s++;
1024    }
1025    *p = '\0';
1026
1027    return r;
1028}
1029
1030/* Add backslashes before colons. */
1031
1032static char *
1033bslashcolon(char *s)
1034{
1035    char *p, *r;
1036
1037    r = p = zhalloc((2 * strlen(s)) + 1);
1038
1039    while (*s) {
1040	if (*s == ':')
1041	    *p++ = '\\';
1042	*p++ = *s++;
1043    }
1044    *p = '\0';
1045
1046    return r;
1047}
1048
1049/* Parse an argument definition. */
1050
1051static Caarg
1052parse_caarg(int mult, int type, int num, int opt, char *oname, char **def,
1053	    char *set)
1054{
1055    Caarg ret = (Caarg) zalloc(sizeof(*ret));
1056    char *p = *def, *d, sav;
1057
1058    ret->next = NULL;
1059    ret->descr = ret->action = ret->end = NULL;
1060    ret->xor = NULL;
1061    ret->num = num;
1062    ret->min = num - opt;
1063    ret->type = type;
1064    ret->opt = ztrdup(oname);
1065    ret->direct = 0;
1066    ret->set = set;
1067
1068    /* Get the description. */
1069
1070    for (d = p; *p && *p != ':'; p++)
1071	if (*p == '\\' && p[1])
1072	    p++;
1073    sav = *p;
1074    *p = '\0';
1075    ret->descr = ztrdup(rembslashcolon(d));
1076
1077    /* Get the action if there is one. */
1078
1079    if (sav) {
1080	if (mult) {
1081	    for (d = ++p; *p && *p != ':'; p++)
1082		if (*p == '\\' && p[1])
1083		    p++;
1084	    sav = *p;
1085	    *p = '\0';
1086	    ret->action = ztrdup(rembslashcolon(d));
1087	    if (sav)
1088		*p = ':';
1089	} else
1090	    ret->action = ztrdup(rembslashcolon(p + 1));
1091    } else
1092	ret->action = ztrdup("");
1093    *def = p;
1094
1095    return ret;
1096}
1097
1098static Cadef
1099alloc_cadef(char **args, int single, char *match, char *nonarg, int flags)
1100{
1101    Cadef ret;
1102
1103    ret = (Cadef) zalloc(sizeof(*ret));
1104    ret->next = ret->snext = NULL;
1105    ret->opts = NULL;
1106    ret->args = ret->rest = NULL;
1107    ret->nonarg = ztrdup(nonarg);
1108    if (args) {
1109	ret->defs = zarrdup(args);
1110	ret->ndefs = arrlen(args);
1111    } else {
1112	ret->defs = NULL;
1113	ret->ndefs = 0;
1114    }
1115    ret->lastt = time(0);
1116    ret->set = ret->sname = NULL;
1117    if (single) {
1118	ret->single = (Caopt *) zalloc(256 * sizeof(Caopt));
1119	memset(ret->single, 0, 256 * sizeof(Caopt));
1120    } else
1121	ret->single = NULL;
1122    ret->match = ztrdup(match);
1123    ret->flags = flags;
1124
1125    return ret;
1126}
1127
1128static void
1129set_cadef_opts(Cadef def)
1130{
1131    Caarg argp;
1132    int xnum;
1133
1134    for (argp = def->args, xnum = 0; argp; argp = argp->next) {
1135	if (!argp->direct)
1136	    argp->min = argp->num - xnum;
1137	if (argp->type == CAA_OPT)
1138	    xnum++;
1139    }
1140}
1141
1142/* Parse an array of definitions. */
1143
1144static Cadef
1145parse_cadef(char *nam, char **args)
1146{
1147    Cadef all, ret;
1148    Caopt *optp;
1149    char **orig_args = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor, **sargs;
1150    char *adpre, *adsuf, *axor = NULL, *doset = NULL, **setp = NULL;
1151    char *nonarg = NULL;
1152    int single = 0, anum = 1, xnum, nopts, ndopts, nodopts, flags = 0;
1153    int state = 0, not = 0;
1154
1155    nopts = ndopts = nodopts = 0;
1156
1157    /* First string is the auto-description definition. */
1158
1159    for (p = args[0]; *p && (p[0] != '%' || p[1] != 'd'); p++);
1160
1161    if (*p) {
1162	*p = '\0';
1163	adpre = dupstring(args[0]);
1164	*p = '%';
1165	adsuf = dupstring(p + 2);
1166    } else
1167	adpre = adsuf = NULL;
1168
1169    /* Now get the -s, -A, -S and -M options. */
1170
1171    args++;
1172    while ((p = *args) && *p == '-' && p[1]) {
1173	for (q = ++p; *q; q++)
1174	    if (*q == 'M' || *q == 'A') {
1175		q = "";
1176		break;
1177	    } else if (*q != 's' && *q != 'S')
1178		break;
1179
1180	if (*q)
1181	    break;
1182
1183	for (; *p; p++) {
1184	    if (*p == 's')
1185		single = 1;
1186	    else if (*p == 'S')
1187		flags |= CDF_SEP;
1188	    else if (*p == 'A') {
1189		if (p[1]) {
1190		    nonarg = p + 1;
1191		    p = "" - 1;
1192		} else if (args[1])
1193		    nonarg = *++args;
1194		else
1195		    break;
1196	    } else if (*p == 'M') {
1197		if (p[1]) {
1198		    match = p + 1;
1199		    p = "" - 1;
1200		} else if (args[1])
1201		    match = *++args;
1202		else
1203		    break;
1204	    }
1205	}
1206	if (*p)
1207	    break;
1208
1209	args++;
1210    }
1211    if (*args && !strcmp(*args, ":"))
1212        args++;
1213    if (!*args)
1214	return NULL;
1215
1216    if (nonarg)
1217	tokenize(nonarg = dupstring(nonarg));
1218
1219    /* Looks good. Optimistically allocate the cadef structure. */
1220
1221    all = ret = alloc_cadef(orig_args, single, match, nonarg, flags);
1222    optp = &(ret->opts);
1223    anum = 1;
1224
1225    sargs = args;
1226
1227    /* Get the definitions. */
1228
1229    for (; *args; args++) {
1230        if (args[0][0] == '-' && !args[0][1] && args[1]) {
1231	    if (!state) {
1232		char *p;
1233		int l;
1234
1235		if (setp)
1236		    args = setp;
1237		p = *++args;
1238		l = strlen(p) - 1;
1239		if (*p == '(' && p[l] == ')') {
1240		    axor = p = dupstring(p + 1);
1241		    p[l - 1] = '\0';
1242		} else
1243		    axor = NULL;
1244		ret->set = doset = tricat(p, "-", "");
1245		ret->sname = ztrdup(p);
1246		state = 1;
1247	    } else {
1248		setp = args;
1249		state = 0;
1250		args = sargs - 1;
1251		doset = NULL;
1252		ret->nopts = nopts;
1253		ret->ndopts = ndopts;
1254		ret->nodopts = nodopts;
1255		set_cadef_opts(ret);
1256		ret = ret->snext = alloc_cadef(NULL, single, NULL, nonarg, flags);
1257		optp = &(ret->opts);
1258		nopts = ndopts = nodopts = 0;
1259		anum = 1;
1260	    }
1261	    continue;
1262	}
1263	p = dupstring(*args);
1264	xnum = 0;
1265	if ((not = (*p == '!')))
1266	    p++;
1267	if (*p == '(') {
1268	    /* There is a xor list, get it. */
1269
1270	    LinkList list = newlinklist();
1271	    LinkNode node;
1272	    char **xp, sav;
1273
1274	    while (*p && *p != ')') {
1275		for (p++; inblank(*p); p++);
1276
1277		if (*p == ')')
1278		    break;
1279		for (q = p++; *p && *p != ')' && !inblank(*p); p++);
1280
1281		if (!*p)
1282		    break;
1283
1284		sav = *p;
1285		*p = '\0';
1286		addlinknode(list, dupstring(q));
1287		xnum++;
1288		*p = sav;
1289	    }
1290	    /* Oops, end-of-string. */
1291	    if (*p != ')') {
1292		freecadef(all);
1293		zwarnnam(nam, "invalid argument: %s", *args);
1294		return NULL;
1295	    }
1296	    if (doset && axor)
1297		xnum++;
1298	    xor = (char **) zalloc((xnum + 2) * sizeof(char *));
1299	    for (node = firstnode(list), xp = xor; node; incnode(node), xp++)
1300		*xp = ztrdup((char *) getdata(node));
1301	    if (doset && axor)
1302		*xp++ = ztrdup(axor);
1303	    xp[0] = xp[1] = NULL;
1304
1305	    p++;
1306	} else if (doset && axor) {
1307	    xnum = 1;
1308	    xor = (char **) zalloc(3 * sizeof(char *));
1309	    xor[0] = ztrdup(axor);
1310	    xor[1] = xor[2] = NULL;
1311	} else
1312	    xor = NULL;
1313
1314	if (*p == '-' || *p == '+' ||
1315	    (*p == '*' && (p[1] == '-' || p[1] == '+'))) {
1316	    /* It's an option. */
1317	    Caopt opt;
1318	    Caarg oargs = NULL;
1319	    int multi, otype = CAO_NEXT, again = 0;
1320	    char *name, *descr, c, *againp = NULL;
1321
1322	    rec:
1323
1324	    /* Allowed more than once? */
1325	    if ((multi = (*p == '*')))
1326		p++;
1327
1328	    if (((p[0] == '-' && p[1] == '+') ||
1329		 (p[0] == '+' && p[1] == '-')) &&
1330		p[2] && p[2] != ':' && p[2] != '[' &&
1331		p[2] != '=' && p[2] != '-' && p[2] != '+') {
1332		/* It's a -+ or +- definition. We just execute the whole
1333		 * stuff twice for such things. */
1334		againp = dupstring(p);
1335		name = ++p;
1336		*p = (again ? '-' : '+');
1337		again++;
1338	    } else {
1339		name = p;
1340		/* If it's a long option skip over the first `-'. */
1341		if (p[0] == '-' && p[1] == '-')
1342		    p++;
1343	    }
1344	    if (!p[1]) {
1345		freecadef(all);
1346		zwarnnam(nam, "invalid argument: %s", *args);
1347		return NULL;
1348	    }
1349
1350	    /* Skip over the name. */
1351	    for (p++; *p && *p != ':' && *p != '[' &&
1352		     ((*p != '-' && *p != '+') ||
1353		      (p[1] != ':' && p[1] != '[')) &&
1354		     (*p != '=' ||
1355		      (p[1] != ':' && p[1] != '[' && p[1] != '-')); p++)
1356		if (*p == '\\' && p[1])
1357		    p++;
1358
1359	    /* The character after the option name specifies the type. */
1360	    c = *p;
1361	    *p = '\0';
1362	    if (c == '-') {
1363		otype = CAO_DIRECT;
1364		c = *++p;
1365	    } else if (c == '+') {
1366		otype = CAO_ODIRECT;
1367		c = *++p;
1368	    } else if (c == '=') {
1369		otype = CAO_OEQUAL;
1370		if ((c = *++p) == '-') {
1371		    otype = CAO_EQUAL;
1372		    c = *++p;
1373		}
1374	    }
1375	    /* Get the optional description, if any. */
1376	    if (c == '[') {
1377		for (descr = ++p; *p && *p != ']'; p++)
1378		    if (*p == '\\' && p[1])
1379			p++;
1380
1381		if (!*p) {
1382		    freecadef(all);
1383		    zwarnnam(nam, "invalid option definition: %s", *args);
1384		    return NULL;
1385		}
1386		*p++ = '\0';
1387		c = *p;
1388	    } else
1389		descr = NULL;
1390
1391	    if (c && c != ':') {
1392		freecadef(all);
1393		zwarnnam(nam, "invalid option definition: %s", *args);
1394		return NULL;
1395	    }
1396	    /* Add the option name to the xor list if not `*-...'. */
1397	    if (!multi) {
1398		if (!xor) {
1399		    xor = (char **) zalloc(2 * sizeof(char *));
1400		    xor[0] = xor[1] = NULL;
1401		}
1402                zsfree(xor[xnum]);
1403		xor[xnum] = ztrdup(rembslashcolon(name));
1404	    }
1405	    if (c == ':') {
1406		/* There's at least one argument. */
1407
1408		Caarg *oargp = &oargs;
1409		int atype, rest, oanum = 1, onum = 0;
1410		char *end;
1411
1412		/* Loop over the arguments. */
1413
1414		while (c == ':') {
1415		    rest = 0;
1416		    end = NULL;
1417
1418		    /* Get the argument type. */
1419		    if (*++p == ':') {
1420			atype = CAA_OPT;
1421			p++;
1422		    } else if (*p == '*') {
1423			if (*++p != ':') {
1424			    char sav;
1425
1426			    for (end = p++; *p && *p != ':'; p++)
1427				if (*p == '\\' && p[1])
1428				    p++;
1429			    sav = *p;
1430			    *p = '\0';
1431			    end = dupstring(end);
1432			    tokenize(end);
1433			    *p = sav;
1434			}
1435			if (*p != ':') {
1436			    freecadef(all);
1437			    freecaargs(oargs);
1438			    zwarnnam(nam, "invalid option definition: %s",
1439				    *args);
1440			    return NULL;
1441			}
1442			if (*++p == ':') {
1443			    if (*++p == ':') {
1444				atype = CAA_RREST;
1445				p++;
1446			    } else
1447				atype = CAA_RARGS;
1448			} else
1449			    atype = CAA_REST;
1450			rest = 1;
1451		    } else
1452			atype = CAA_NORMAL;
1453
1454		    /* And the definition. */
1455
1456		    *oargp = parse_caarg(!rest, atype, oanum++, onum,
1457					 name, &p, doset);
1458		    if (atype == CAA_OPT)
1459			onum++;
1460		    if (end)
1461			(*oargp)->end = ztrdup(end);
1462		    oargp = &((*oargp)->next);
1463		    if (rest)
1464			break;
1465		    c = *p;
1466		}
1467	    }
1468	    /* Store the option definition. */
1469
1470	    *optp = opt = (Caopt) zalloc(sizeof(*opt));
1471	    optp = &((*optp)->next);
1472
1473	    opt->next = NULL;
1474	    opt->set = doset;
1475	    opt->name = ztrdup(rembslashcolon(name));
1476	    if (descr)
1477		opt->descr = ztrdup(descr);
1478	    else if (adpre && oargs && !oargs->next) {
1479		char *d;
1480
1481		for (d = oargs->descr; *d; d++)
1482		    if (!iblank(*d))
1483			break;
1484
1485		if (*d)
1486		    opt->descr = tricat(adpre, oargs->descr, adsuf);
1487		else
1488		    opt->descr = NULL;
1489	    } else
1490		opt->descr = NULL;
1491	    opt->xor = (again == 1 && xor ? zarrdup(xor) : xor);
1492	    opt->type = otype;
1493	    opt->args = oargs;
1494	    opt->num = nopts++;
1495	    opt->not = not;
1496
1497	    if (otype == CAO_DIRECT || otype == CAO_EQUAL)
1498		ndopts++;
1499	    else if (otype == CAO_ODIRECT || otype == CAO_OEQUAL)
1500		nodopts++;
1501
1502	    /* If this is for single-letter option we also store a
1503	     * pointer for the definition in the array for fast lookup. */
1504
1505	    if (single && name[1] && !name[2])
1506		ret->single[STOUC(name[1])] = opt;
1507
1508	    if (again == 1) {
1509		/* Do it all again for `*-...'. */
1510		p = againp;
1511		goto rec;
1512	    }
1513	} else if (*p == '*') {
1514	    /* It's a rest-argument definition. */
1515
1516	    int type = CAA_REST;
1517
1518	    if (not)
1519		continue;
1520
1521	    if (*++p != ':') {
1522		freecadef(all);
1523		zwarnnam(nam, "invalid rest argument definition: %s", *args);
1524		return NULL;
1525	    }
1526	    if (ret->rest) {
1527		freecadef(all);
1528		zwarnnam(nam, "doubled rest argument definition: %s", *args);
1529		return NULL;
1530	    }
1531	    if (*++p == ':') {
1532		if (*++p == ':') {
1533		    type = CAA_RREST;
1534		    p++;
1535		} else
1536		    type = CAA_RARGS;
1537	    }
1538	    ret->rest = parse_caarg(0, type, -1, 0, NULL, &p, doset);
1539	    ret->rest->xor = xor;
1540	} else {
1541	    /* It's a normal argument definition. */
1542
1543	    int type = CAA_NORMAL, direct;
1544	    Caarg arg, tmp, pre;
1545
1546	    if (not)
1547		continue;
1548
1549	    if ((direct = idigit(*p))) {
1550		/* Argment number is given. */
1551		int num = 0;
1552
1553		while (*p && idigit(*p))
1554		    num = (num * 10) + (((int) *p++) - '0');
1555
1556		anum = num + 1;
1557	    } else
1558		/* Default number. */
1559		anum++;
1560
1561	    if (*p != ':') {
1562		freecadef(all);
1563		zwarnnam(nam, "invalid argument: %s", *args);
1564		if (xor)
1565		    free(xor);
1566		return NULL;
1567	    }
1568	    if (*++p == ':') {
1569		/* Optional argument. */
1570		type = CAA_OPT;
1571		p++;
1572	    }
1573	    arg = parse_caarg(0, type, anum - 1, 0, NULL, &p, doset);
1574	    arg->xor = xor;
1575	    arg->direct = direct;
1576
1577	    /* Sort the new definition into the existing list. */
1578
1579	    for (tmp = ret->args, pre = NULL;
1580		 tmp && tmp->num < anum - 1;
1581		 pre = tmp, tmp = tmp->next);
1582
1583	    if (tmp && tmp->num == anum - 1) {
1584		freecadef(all);
1585		freecaargs(arg);
1586		zwarnnam(nam, "doubled argument definition: %s", *args);
1587		return NULL;
1588	    }
1589	    arg->next = tmp;
1590	    if (pre)
1591		pre->next = arg;
1592	    else
1593		ret->args = arg;
1594	}
1595    }
1596    ret->nopts = nopts;
1597    ret->ndopts = ndopts;
1598    ret->nodopts = nodopts;
1599    set_cadef_opts(ret);
1600
1601    return all;
1602}
1603
1604/* Given an array of definitions, return the cadef for it. From the cache
1605 * are newly built. */
1606
1607static Cadef
1608get_cadef(char *nam, char **args)
1609{
1610    Cadef *p, *min, new;
1611    int i, na = arrlen(args);
1612
1613    for (i = MAX_CACACHE, p = cadef_cache, min = NULL; i && *p; p++, i--)
1614	if (*p && na == (*p)->ndefs && arrcmp(args, (*p)->defs)) {
1615	    (*p)->lastt = time(0);
1616
1617	    return *p;
1618	} else if (!min || !*p || (*p)->lastt < (*min)->lastt)
1619	    min = p;
1620    if (i > 0)
1621	min = p;
1622    if ((new = parse_cadef(nam, args))) {
1623	freecadef(*min);
1624	*min = new;
1625    }
1626    return new;
1627}
1628
1629/*
1630 * Get the option used in a word from the line, if any.
1631 *
1632 * "d" is a complete set of argument/option definitions to scan.
1633 * "line" is the word we are scanning.
1634 * "full" indicates that the option must match a full word; otherwise
1635 *   we look for "=" arguments or prefixes.
1636 * *"end" is set to point to the end of the option, in some cases
1637 *   leaving an option argument after it.
1638 */
1639
1640static Caopt
1641ca_get_opt(Cadef d, char *line, int full, char **end)
1642{
1643    Caopt p;
1644
1645    /* The full string may be an option. */
1646
1647    for (p = d->opts; p; p = p->next)
1648	if (p->active && !strcmp(p->name, line)) {
1649	    if (end)
1650		*end = line + strlen(line);
1651
1652	    return p;
1653	}
1654
1655    if (!full) {
1656	/* The string from the line probably only begins with an option. */
1657	for (p = d->opts; p; p = p->next)
1658	    if (p->active && ((!p->args || p->type == CAO_NEXT) ?
1659			      !strcmp(p->name, line) : strpfx(p->name, line))) {
1660		if (end) {
1661		    /* Return a pointer to the end of the option. */
1662		    int l = strlen(p->name);
1663
1664		    if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
1665			line[l] == '=')
1666			l++;
1667
1668		    *end = line + l;
1669		}
1670		return p;
1671	    }
1672    }
1673    return NULL;
1674}
1675
1676/* Same as above, only for single-letter-style. */
1677
1678static Caopt
1679ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp)
1680{
1681    Caopt p, pp = NULL;
1682    char pre = *line++;
1683    LinkList l = NULL;
1684
1685    *lp = NULL;
1686    for (p = NULL; *line; line++) {
1687	if ((p = d->single[STOUC(*line)]) && p->active &&
1688	    p->args && p->name[0] == pre) {
1689	    if (p->type == CAO_NEXT) {
1690		if (!l)
1691		    *lp = l = newlinklist();
1692		addlinknode(l, p);
1693	    } else {
1694		if (end) {
1695		    line++;
1696		    if ((p->type == CAO_OEQUAL || p->type == CAO_EQUAL) &&
1697			*line == '=')
1698			line++;
1699		    *end = line;
1700		}
1701		pp = p;
1702		break;
1703	    }
1704	} else if (!p || (p && !p->active))
1705	    return NULL;
1706	pp = (p->name[0] == pre ? p : NULL);
1707	p = NULL;
1708    }
1709    if (pp && end)
1710	*end = line;
1711    return pp;
1712}
1713
1714/* Return the n'th argument definition. */
1715
1716static Caarg
1717ca_get_arg(Cadef d, int n)
1718{
1719    if (d->argsactive) {
1720	Caarg a = d->args;
1721
1722	while (a && (!a->active || n < a->min || n > a->num)) {
1723            if (!a->active)
1724                n++;
1725	    a = a->next;
1726        }
1727	if (a && a->min <= n && a->num >= n && a->active)
1728	    return a;
1729
1730	return (d->rest && d->rest->active ? d->rest : NULL);
1731    }
1732    return NULL;
1733}
1734
1735/* Use a xor list, marking options as inactive. */
1736
1737static LinkList ca_xor;
1738
1739static int
1740ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname)
1741{
1742    if ((xor || opts) && cur <= compcurrent) {
1743	Caopt opt;
1744	char *x;
1745	int sl = (d->set ? (int)strlen(d->set) : -1), set = 0;
1746
1747	for (; (x = (opts ? "-" : *xor)); xor++) {
1748            if (optname && optname[0] == x[0] && strcmp(optname, x))
1749                continue;
1750	    if (ca_xor)
1751		addlinknode(ca_xor, x);
1752	    set = 0;
1753	    if (sl > 0) {
1754		if (strpfx(d->set, x)) {
1755		    x += sl;
1756		    set = 1;
1757		} else if (!strncmp(d->set, x, sl - 1)) {
1758		    Caopt p;
1759
1760		    for (p = d->opts; p; p = p->next)
1761			if (p->set)
1762			    p->active = 0;
1763
1764		    x = ":";
1765		    set = 1;
1766		}
1767	    }
1768	    if (x[0] == ':' && !x[1]) {
1769		if (set) {
1770		    Caarg a;
1771
1772		    for (a = d->args; a; a = a->next)
1773			if (a->set)
1774			    a->active = 0;
1775		    if (d->rest && (!set || d->rest->set))
1776			d->rest->active = 0;
1777		} else
1778		    d->argsactive = 0;
1779	    } else if (x[0] == '-' && !x[1]) {
1780		Caopt p;
1781
1782		for (p = d->opts; p; p = p->next)
1783		    if (!set || p->set)
1784			p->active = 0;
1785	    } else if (x[0] == '*' && !x[1]) {
1786		if (d->rest && (!set || d->rest->set))
1787		    d->rest->active = 0;
1788	    } else if (idigit(x[0])) {
1789		int n = atoi(x);
1790		Caarg a = d->args;
1791
1792		while (a && a->num < n)
1793		    a = a->next;
1794
1795		if (a && a->num == n && (!set || a->set))
1796		    a->active = 0;
1797	    } else if ((opt = ca_get_opt(d, x, 1, NULL)) && (!set || opt->set))
1798		opt->active = 0;
1799
1800	    if (opts)
1801		break;
1802	}
1803    }
1804    return 0;
1805}
1806
1807/* State when parsing a command line. */
1808
1809typedef struct castate *Castate;
1810
1811/*
1812 *           **** DOCUMENT ME ****
1813 *
1814 * This structure and its use are a nightmare.
1815 */
1816
1817struct castate {
1818    Castate snext;
1819    Cadef d;
1820    int nopts;
1821    Caarg def, ddef;
1822    Caopt curopt, dopt;
1823    int opt, arg, argbeg, optbeg, nargbeg, restbeg, curpos, argend;
1824    int inopt, inrest, inarg, nth, doff, singles, oopt, actopts;
1825    LinkList args;
1826    LinkList *oargs;
1827};
1828
1829static struct castate ca_laststate;
1830static int ca_parsed = 0, ca_alloced = 0;
1831
1832static void
1833freecastate(Castate s)
1834{
1835    int i;
1836    LinkList *p;
1837
1838    freelinklist(s->args, freestr);
1839    for (i = s->nopts, p = s->oargs; i--; p++)
1840	if (*p)
1841	    freelinklist(*p, freestr);
1842    zfree(s->oargs, s->d->nopts * sizeof(LinkList));
1843}
1844
1845/* Return a copy of an option's argument, ignoring possible quoting
1846 * in the option name. */
1847
1848static char *
1849ca_opt_arg(Caopt opt, char *line)
1850{
1851    char *o = opt->name;
1852
1853    while (1) {
1854        if (*o == '\\')
1855            o++;
1856        if (*line == '\\' || *line == '\'' || *line == '"')
1857            line++;
1858        if (!*o || *o != *line)
1859            break;
1860        o++;
1861        line++;
1862    }
1863    if (*line && (opt->type == CAO_EQUAL || opt->type == CAO_OEQUAL)) {
1864        if (*line == '\\')
1865            line++;
1866        if (*line == '=')
1867            line++;
1868    }
1869    return ztrdup(line);
1870}
1871
1872/* Parse a command line. */
1873
1874static int
1875ca_parse_line(Cadef d, int multi, int first)
1876{
1877    Caarg adef, ddef;
1878    Caopt ptr, wasopt = NULL, dopt;
1879    struct castate state;
1880    char *line, *oline, *pe, **argxor = NULL;
1881    int cur, doff, argend, arglast;
1882    Patprog endpat = NULL, napat = NULL;
1883    LinkList sopts = NULL;
1884#if 0
1885    int ne;
1886#endif
1887
1888    /* Free old state. */
1889
1890    if (first && ca_alloced) {
1891	Castate s = &ca_laststate, ss;
1892
1893	while (s) {
1894	    ss = s->snext;
1895	    freecastate(s);
1896	    s = ss;
1897	}
1898    }
1899    /* Mark everything as active. */
1900
1901    for (ptr = d->opts; ptr; ptr = ptr->next)
1902	ptr->active = 1;
1903    d->argsactive = 1;
1904    if (d->rest)
1905	d->rest->active = 1;
1906    for (adef = d->args; adef; adef = adef->next)
1907	adef->active = 1;
1908
1909    /* Default values for the state. */
1910
1911    state.snext = NULL;
1912    state.d = d;
1913    state.nopts = d->nopts;
1914    state.def = state.ddef = NULL;
1915    state.curopt = state.dopt = NULL;
1916    state.argbeg = state.optbeg = state.nargbeg = state.restbeg = state.actopts =
1917	state.nth = state.inopt = state.inarg = state.opt = state.arg = 1;
1918    state.argend = argend = arrlen(compwords) - 1;
1919    state.inrest = state.doff = state.singles = state.oopt = 0;
1920    state.curpos = compcurrent;
1921    state.args = znewlinklist();
1922    state.oargs = (LinkList *) zalloc(d->nopts * sizeof(LinkList));
1923    memset(state.oargs, 0, d->nopts * sizeof(LinkList));
1924
1925    ca_alloced = 1;
1926
1927    memcpy(&ca_laststate, &state, sizeof(state));
1928
1929    if (!compwords[1]) {
1930	ca_laststate.opt = ca_laststate.arg = 0;
1931
1932	goto end;
1933    }
1934    if (d->nonarg)
1935	napat = patcompile(d->nonarg, 0, NULL);
1936
1937    /* Loop over the words from the line. */
1938
1939    for (line = compwords[1], cur = 2, state.curopt = NULL, state.def = NULL;
1940	 line; line = compwords[cur++]) {
1941	ddef = adef = NULL;
1942	dopt = NULL;
1943	doff = state.singles = arglast = 0;
1944
1945        oline = line;
1946#if 0
1947        /*
1948	 * remove quotes.
1949	 * This is commented out:  it doesn't allow you to discriminate
1950	 * between command line values that can be expanded and those
1951	 * that can't, and in some cases this generates inconsistency;
1952	 * for example, ~/foo\[bar unqotes to ~/foo[bar which doesn't
1953	 * work either way---it's wrong if the ~ is quoted, and
1954	 * wrong if the [ isn't quoted..  So it's now up to the caller to
1955	 * unquote.
1956	 */
1957        line = dupstring(line);
1958        ne = noerrs;
1959        noerrs = 2;
1960        parse_subst_string(line);
1961        noerrs = ne;
1962#endif
1963        remnulargs(line);
1964        untokenize(line);
1965
1966	if (ca_inactive(d, argxor, cur, 0, NULL) ||
1967	    ((d->flags & CDF_SEP) && cur != compcurrent && !strcmp(line, "--"))) {
1968	    if (ca_inactive(d, NULL, cur, 1, NULL))
1969		return 1;
1970	    continue;
1971	}
1972	/* We've got a definition for an argument, skip to the next. */
1973
1974	if (state.def) {
1975	    state.arg = 0;
1976	    if (state.curopt)
1977		zaddlinknode(state.oargs[state.curopt->num], ztrdup(oline));
1978
1979	    if ((state.opt = (state.def->type == CAA_OPT)) && state.def->opt)
1980		state.oopt++;
1981
1982	    if (state.def->type == CAA_REST || state.def->type == CAA_RARGS ||
1983		state.def->type == CAA_RREST) {
1984		if (state.def->end && pattry(endpat, line)) {
1985		    state.def = NULL;
1986		    state.curopt = NULL;
1987		    state.opt = state.arg = 1;
1988		    state.argend = ca_laststate.argend = cur - 1;
1989		    goto cont;
1990		}
1991	    } else if ((state.def = state.def->next)) {
1992		state.argbeg = cur;
1993		state.argend = argend;
1994	    } else if (sopts && nonempty(sopts)) {
1995		state.curopt = (Caopt) uremnode(sopts, firstnode(sopts));
1996		state.def = state.curopt->args;
1997		state.opt = 0;
1998		state.argbeg = state.optbeg = state.inopt = cur;
1999		state.argend = argend;
2000		doff = state.doff = 0;
2001		state.singles = 1;
2002		if (!state.oargs[state.curopt->num])
2003		    state.oargs[state.curopt->num] = znewlinklist();
2004		goto cont;
2005	    } else {
2006		state.curopt = NULL;
2007		state.opt = 1;
2008	    }
2009	} else {
2010	    state.opt = state.arg = 1;
2011	    state.curopt = NULL;
2012	}
2013	if (state.opt)
2014	    state.opt = (line[0] ? (line[1] ? 2 : 1) : 0);
2015
2016	pe = NULL;
2017
2018	wasopt = NULL;
2019
2020	/* See if it's an option. */
2021
2022	if (state.opt == 2 && (state.curopt = ca_get_opt(d, line, 0, &pe)) &&
2023	    (state.curopt->type == CAO_OEQUAL ?
2024	     (compwords[cur] || pe[-1] == '=') :
2025	     (state.curopt->type == CAO_EQUAL ?
2026	      (pe[-1] == '=' || !pe[0]) : 1))) {
2027
2028	    if ((ddef = state.def = ((state.curopt->type != CAO_EQUAL ||
2029				      pe[-1] == '=') ?
2030				     state.curopt->args : NULL)))
2031		dopt = state.curopt;
2032
2033	    doff = pe - line;
2034	    state.optbeg = state.argbeg = state.inopt = cur;
2035	    state.argend = argend;
2036	    state.singles = (d->single && (!pe || !*pe) &&
2037			     state.curopt->name[1] && !state.curopt->name[2]);
2038
2039	    if (!state.oargs[state.curopt->num])
2040		state.oargs[state.curopt->num] = znewlinklist();
2041
2042	    if (ca_inactive(d, state.curopt->xor, cur, 0,
2043                            (cur == compcurrent ? state.curopt->name : NULL)))
2044		return 1;
2045
2046	    /* Collect the argument strings. Maybe. */
2047
2048	    if (state.def &&
2049		(state.curopt->type == CAO_DIRECT ||
2050		 state.curopt->type == CAO_EQUAL ||
2051		 (state.curopt->type == CAO_ODIRECT && pe[0]) ||
2052		 (state.curopt->type == CAO_OEQUAL &&
2053		  (pe[0] || pe[-1] == '=')))) {
2054		if (state.def->type != CAA_REST &&
2055		    state.def->type != CAA_RARGS &&
2056		    state.def->type != CAA_RREST)
2057		    state.def = state.def->next;
2058
2059		zaddlinknode(state.oargs[state.curopt->num],
2060                             ca_opt_arg(state.curopt, oline));
2061	    }
2062	    if (state.def)
2063		state.opt = 0;
2064	    else {
2065		if (!d->single || (state.curopt->name[1] && state.curopt->name[2]))
2066		    wasopt = state.curopt;
2067		state.curopt = NULL;
2068	    }
2069	} else if (state.opt == 2 && d->single &&
2070		   ((state.curopt = ca_get_sopt(d, line, &pe, &sopts)) ||
2071		    (cur != compcurrent && sopts && nonempty(sopts)))) {
2072	    /* Or maybe it's a single-letter option? */
2073
2074	    char *p;
2075	    Caopt tmpopt;
2076
2077	    if (cur != compcurrent && sopts && nonempty(sopts))
2078		state.curopt = (Caopt) uremnode(sopts, firstnode(sopts));
2079
2080	    if (!state.oargs[state.curopt->num])
2081		state.oargs[state.curopt->num] = znewlinklist();
2082
2083	    state.def = state.curopt->args;
2084	    ddef = (state.curopt->type == CAO_NEXT && cur == compcurrent ?
2085		    NULL : state.def);
2086	    dopt = state.curopt;
2087	    doff = pe - line;
2088	    state.optbeg = state.argbeg = state.inopt = cur;
2089	    state.argend = argend;
2090	    state.singles = (!pe || !*pe);
2091
2092	    for (p = line + 1; p < pe; p++) {
2093		if ((tmpopt = d->single[STOUC(*p)])) {
2094		    if (!state.oargs[tmpopt->num])
2095			state.oargs[tmpopt->num] = znewlinklist();
2096
2097		    if (ca_inactive(d, tmpopt->xor, cur, 0,
2098                                    (cur == compcurrent ? tmpopt->name : NULL)))
2099			return 1;
2100		}
2101	    }
2102	    if (state.def &&
2103		(state.curopt->type == CAO_DIRECT ||
2104		 state.curopt->type == CAO_EQUAL ||
2105		 (state.curopt->type == CAO_ODIRECT && pe[0]) ||
2106		 (state.curopt->type == CAO_OEQUAL &&
2107		  (pe[0] || pe[-1] == '=')))) {
2108		if (state.def->type != CAA_REST &&
2109		    state.def->type != CAA_RARGS &&
2110		    state.def->type != CAA_RREST)
2111		    state.def = state.def->next;
2112
2113		zaddlinknode(state.oargs[state.curopt->num],
2114                             ca_opt_arg(state.curopt, line));
2115	    }
2116	    if (state.def)
2117		state.opt = 0;
2118	    else
2119		state.curopt = NULL;
2120	} else if (multi && (*line == '-' || *line == '+') && cur != compcurrent
2121#if 0
2122		   /**** Ouch. Using this will disable the mutual exclusion
2123			 of different sets. Not using it will make the -A
2124			 pattern be effectively ignored with multiple sets. */
2125		   && (!napat || !pattry(napat, line))
2126#endif
2127		   )
2128	    return 1;
2129	else if (state.arg && (!napat || !pattry(napat, line))) {
2130	    /* Otherwise it's a normal argument. */
2131	    if (napat && ca_inactive(d, NULL, cur + 1, 1, NULL))
2132		return 1;
2133
2134	    arglast = 1;
2135	    if (state.inopt) {
2136		state.inopt = 0;
2137		state.nargbeg = cur - 1;
2138		state.argend = argend;
2139	    }
2140	    if (!d->args && !d->rest && *line && *line != '-' && *line != '+') {
2141		if (!multi && cur > compcurrent)
2142		    break;
2143		return 1;
2144	    }
2145	    if ((adef = state.def = ca_get_arg(d, state.nth)) &&
2146		(state.def->type == CAA_RREST ||
2147		 state.def->type == CAA_RARGS)) {
2148
2149		/* Bart 2009/11/17:
2150		 * We've reached the "rest" definition.  If at this point
2151		 * we already found another definition that describes the
2152		 * current word, use that instead.  If not, prep for the
2153		 * "narrowing" of scope to only the remaining words.
2154		 *
2155		 * We can't test ca_laststate.def in the loop conditions
2156		 * at the top because this same loop also handles the
2157		 * ':*PATTERN:MESSAGE:ACTION' form for multiple arguments
2158		 * after an option, which may need to continue scanning.
2159		 * There might be an earlier point at which this test can
2160		 * be made but tracking it down is not worth the effort.
2161		 */
2162		if (ca_laststate.def)
2163		    break;
2164
2165		state.inrest = 0;
2166		state.opt = (cur == state.nargbeg + 1 &&
2167			     (!multi || !*line ||
2168			      *line == '-' || *line == '+'));
2169		state.optbeg = state.nargbeg;
2170		state.argbeg = cur - 1;
2171		state.argend = argend;
2172
2173		for (; line; line = compwords[cur++])
2174		    zaddlinknode(state.args, ztrdup(line));
2175
2176		memcpy(&ca_laststate, &state, sizeof(state));
2177		ca_laststate.ddef = NULL;
2178		ca_laststate.dopt = NULL;
2179		ca_laststate.doff = 0;
2180		break;
2181	    }
2182	    zaddlinknode(state.args, ztrdup(line));
2183            if (adef)
2184                state.oopt = adef->num - state.nth;
2185
2186	    if (state.def)
2187		argxor = state.def->xor;
2188
2189	    if (state.def && state.def->type != CAA_NORMAL &&
2190		state.def->type != CAA_OPT && state.inarg) {
2191		state.restbeg = cur;
2192		state.inarg = 0;
2193	    } else if (!state.def || state.def->type == CAA_NORMAL ||
2194		       state.def->type == CAA_OPT)
2195		state.inarg = 1;
2196	    state.nth++;
2197	    state.def = NULL;
2198	}
2199	/* Do the end-pattern test if needed. */
2200
2201	if (state.def && state.curopt &&
2202	    (state.def->type == CAA_RREST || state.def->type == CAA_RARGS)) {
2203	    if (state.def->end)
2204		endpat = patcompile(state.def->end, 0, NULL);
2205	    else {
2206		LinkList l = state.oargs[state.curopt->num];
2207
2208		if (cur < compcurrent)
2209		    memcpy(&ca_laststate, &state, sizeof(state));
2210
2211		for (; line; line = compwords[cur++])
2212		    zaddlinknode(l, ztrdup(line));
2213
2214		ca_laststate.ddef = NULL;
2215		ca_laststate.dopt = NULL;
2216		ca_laststate.doff = 0;
2217		break;
2218	    }
2219	} else if (state.def && state.def->end)
2220	    endpat = patcompile(state.def->end, 0, NULL);
2221
2222	/* Copy the state into the global one. */
2223
2224    cont:
2225
2226	if (cur + 1 == compcurrent) {
2227	    memcpy(&ca_laststate, &state, sizeof(state));
2228	    ca_laststate.ddef = NULL;
2229	    ca_laststate.dopt = NULL;
2230	    ca_laststate.doff = 0;
2231	} else if (cur == compcurrent && !ca_laststate.def) {
2232	    if ((ca_laststate.def = ddef)) {
2233		ca_laststate.singles = state.singles;
2234		if (state.curopt && state.curopt->type == CAO_NEXT) {
2235		    ca_laststate.ddef = ddef;
2236		    ca_laststate.dopt = dopt;
2237		    ca_laststate.def = NULL;
2238		    ca_laststate.opt = 1;
2239		    state.curopt->active = 1;
2240		} else {
2241		    ca_laststate.doff = doff;
2242		    ca_laststate.opt = 0;
2243		}
2244	    } else {
2245		ca_laststate.def = adef;
2246		ca_laststate.opt = (!arglast || !multi || !*line ||
2247				    *line == '-' || *line == '+');
2248		ca_laststate.ddef = NULL;
2249		ca_laststate.dopt = NULL;
2250		ca_laststate.optbeg = state.nargbeg;
2251		ca_laststate.argbeg = state.restbeg;
2252		ca_laststate.argend = state.argend;
2253		ca_laststate.singles = state.singles;
2254		ca_laststate.oopt = state.oopt;
2255		if (wasopt)
2256		    wasopt->active = 1;
2257	    }
2258	}
2259    }
2260 end:
2261
2262    ca_laststate.actopts = 0;
2263    for (ptr = d->opts; ptr; ptr = ptr->next)
2264	if (ptr->active)
2265	    ca_laststate.actopts++;
2266
2267    return 0;
2268}
2269
2270/* Build a colon-list from a list. */
2271
2272static char *
2273ca_colonlist(LinkList l)
2274{
2275    if (l) {
2276	LinkNode n;
2277	int len = 0;
2278	char *p, *ret, *q;
2279
2280	for (n = firstnode(l); n; incnode(n)) {
2281	    len++;
2282	    for (p = (char *) getdata(n); *p; p++)
2283		len += (*p == ':' ? 2 : 1);
2284	}
2285	ret = q = (char *) zalloc(len);
2286
2287	for (n = firstnode(l); n;) {
2288	    for (p = (char *) getdata(n); *p; p++) {
2289		if (*p == ':')
2290		    *q++ = '\\';
2291		*q++ = *p;
2292	    }
2293	    incnode(n);
2294	    if (n)
2295		*q++ = ':';
2296	}
2297	*q = '\0';
2298
2299	return ret;
2300    } else
2301	return ztrdup("");
2302}
2303
2304/*
2305 * This function adds the current set of descriptions, actions,
2306 * and subcontext descriptions to the given linked list for passing
2307 * up in comparguments -D and comparguments -L.  opt is the
2308 * option string (may be NULL if this isn't an option argument) and arg the
2309 * argument structure (either an option argument or a normal argument
2310 * as determined by arg->type).
2311 */
2312
2313static void
2314ca_set_data(LinkList descr, LinkList act, LinkList subc,
2315	    char *opt, Caarg arg, Caopt optdef, int single)
2316{
2317    LinkNode dnode, anode;
2318    char nbuf[40], *buf;
2319    int restr = 0, onum, miss = 0, rest, oopt = 1, lopt = 0, addopt;
2320
2321 rec:
2322
2323    addopt = (opt ? 0 : ca_laststate.oopt);
2324
2325    for (; arg && (opt || (arg->num < 0 ||
2326			   (arg->min <= ca_laststate.nth + addopt &&
2327			    arg->num >= ca_laststate.nth)));) {
2328	lopt = (arg->type == CAA_OPT);
2329	if (!opt && !lopt && oopt > 0)
2330	    oopt = 0;
2331
2332	for (dnode = firstnode(descr), anode = firstnode(act);
2333	     dnode; incnode(dnode), incnode(anode))
2334	    if (!strcmp((char *) getdata(dnode), arg->descr) &&
2335		!strcmp((char *) getdata(anode), arg->action))
2336		break;
2337
2338	if (!dnode) {
2339	    addlinknode(descr, arg->descr);
2340	    addlinknode(act, arg->action);
2341
2342	    if (!restr) {
2343		if ((restr = (arg->type == CAA_RARGS)))
2344		    restrict_range(ca_laststate.optbeg, ca_laststate.argend);
2345		else if ((restr = (arg->type == CAA_RREST)))
2346		    restrict_range(ca_laststate.argbeg, ca_laststate.argend);
2347	    }
2348	    if (arg->opt) {
2349		buf = (char *) zhalloc((arg->set ? strlen(arg->set) : 0) +
2350				       strlen(arg->opt) + 40);
2351		if (arg->num > 0 && arg->type < CAA_REST)
2352		    sprintf(buf, "%soption%s-%d",
2353			    (arg->set ? arg->set : ""), arg->opt, arg->num);
2354		else
2355		    sprintf(buf, "%soption%s-rest",
2356			    (arg->set ? arg->set : ""), arg->opt);
2357	    } else if (arg->num > 0) {
2358		sprintf(nbuf, "argument-%d", arg->num);
2359		buf = (arg->set ? dyncat(arg->set, nbuf) : dupstring(nbuf));
2360	    } else
2361		buf = (arg->set ? dyncat(arg->set, "argument-rest") :
2362		       dupstring("argument-rest"));
2363
2364	    addlinknode(subc, buf);
2365	}
2366	/*
2367	 * If this is an argument to an option, and the option definition says
2368	 * the argument to the option is required and in the following
2369	 * (i.e. this) word, then it must match what we've just told it to
2370	 * match---don't try to match normal arguments.
2371	 *
2372	 * This test may be too stringent for what we need, or it
2373	 * may be too loose; I've simply tweaked it until it gets
2374	 * the case above right.
2375	 */
2376	if (arg->type == CAA_NORMAL &&
2377	    opt && optdef && optdef->type == CAO_NEXT)
2378	    return;
2379	if (single)
2380	    break;
2381
2382	if (!opt) {
2383	    if (arg->num >= 0 && !arg->next && miss)
2384		arg = (ca_laststate.d->rest && ca_laststate.d->rest->active ?
2385		       ca_laststate.d->rest : NULL);
2386	    else {
2387		onum = arg->num;
2388		rest = (onum != arg->min && onum == ca_laststate.nth);
2389		if ((arg = arg->next)) {
2390		    if (arg->num != onum + 1)
2391			miss = 1;
2392		} else if (rest || (oopt > 0 && !opt)) {
2393		    arg = (ca_laststate.d->rest && ca_laststate.d->rest->active ?
2394			   ca_laststate.d->rest : NULL);
2395		    oopt = -1;
2396		}
2397	    }
2398	} else {
2399	    if (!lopt)
2400		break;
2401	    arg = arg->next;
2402	}
2403    }
2404    if (!single && opt && (lopt || ca_laststate.oopt)) {
2405	opt = NULL;
2406	arg = ca_get_arg(ca_laststate.d, ca_laststate.nth);
2407
2408	goto rec;
2409    }
2410    if (!opt && oopt > 0) {
2411	oopt = -1;
2412	arg = (ca_laststate.d->rest && ca_laststate.d->rest->active ?
2413	       ca_laststate.d->rest : NULL);
2414
2415	goto rec;
2416    }
2417}
2418
2419static int
2420bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
2421{
2422    int min, max, n;
2423    Castate lstate = &ca_laststate;
2424
2425    if (incompfunc != 1) {
2426	zwarnnam(nam, "can only be called from completion function");
2427	return 1;
2428    }
2429    if (args[0][0] != '-' || !args[0][1] || args[0][2]) {
2430	zwarnnam(nam, "invalid argument: %s", args[0]);
2431	return 1;
2432    }
2433    if (args[0][1] != 'i' && args[0][1] != 'I' && !ca_parsed) {
2434	zwarnnam(nam, "no parsed state");
2435	return 1;
2436    }
2437    switch (args[0][1]) {
2438    case 'i': min = 2; max = -1; break;
2439    case 'D': min = 3; max =  3; break;
2440    case 'O': min = 4; max =  4; break;
2441    case 'L': min = 3; max =  4; break;
2442    case 's': min = 1; max =  1; break;
2443    case 'M': min = 1; max =  1; break;
2444    case 'a': min = 0; max =  0; break;
2445    case 'W': min = 2; max =  2; break;
2446    case 'n': min = 1; max =  1; break;
2447    default:
2448	zwarnnam(nam, "invalid option: %s", args[0]);
2449	return 1;
2450    }
2451    n = arrlen(args) - 1;
2452    if (n < min) {
2453	zwarnnam(nam, "not enough arguments");
2454	return 1;
2455    } else if (max >= 0 && n > max) {
2456	zwarnnam(nam, "too many arguments");
2457	return 1;
2458    }
2459    switch (args[0][1]) {
2460    case 'i':
2461        /* This initialises the internal data structures. Arguments are the
2462         * auto-description string, the optional -s, -S, -A and -M options
2463         * given to _arguments and the specs. */
2464	if (compcurrent > 1 && compwords[0]) {
2465	    Cadef def;
2466	    int cap = ca_parsed, multi, first = 1, use, ret = 0;
2467	    LinkList cax = ca_xor, nx;
2468	    LinkNode node;
2469	    Castate states = NULL, sp;
2470	    char *xor[2];
2471
2472	    ca_parsed = 0;
2473	    xor[1] = NULL;
2474
2475	    if (!(def = get_cadef(nam, args + 1)))
2476		return 1;
2477
2478	    multi = !!def->snext;
2479	    ca_parsed = cap;
2480	    ca_xor = (multi ? newlinklist() : NULL);
2481
2482	    while (def) {
2483		use = !ca_parse_line(def, multi, first);
2484		nx = ca_xor;
2485		ca_xor = NULL;
2486		while ((def = def->snext)) {
2487		    if (nx) {
2488			for (node = firstnode(nx); node; incnode(node)) {
2489			    xor[0] = (char *) getdata(node);
2490			    if (!strcmp(xor[0], def->sname) ||
2491				ca_inactive(def, xor, compcurrent, 0, NULL))
2492				break;
2493			}
2494			if (!node)
2495			    break;
2496		    }
2497		}
2498		ca_xor = nx;
2499		if (use && def) {
2500		    sp = (Castate) zalloc(sizeof(*sp));
2501		    memcpy(sp, &ca_laststate, sizeof(*sp));
2502		    sp->snext = states;
2503		    states = sp;
2504		} else if (!use && !def) {
2505		    if (states) {
2506			freecastate(&ca_laststate);
2507			memcpy(&ca_laststate, states, sizeof(*sp));
2508			sp = states->snext;
2509			zfree(states, sizeof(*states));
2510			states = sp;
2511		    } else
2512			ret = 1;
2513		}
2514		first = 0;
2515	    }
2516	    ca_xor = cax;
2517	    ca_parsed = 1;
2518	    ca_laststate.snext = states;
2519
2520	    return ret;
2521	}
2522	return 1;
2523
2524    case 'D':
2525        /* This returns the descriptions, actions and sub-contexts for the
2526         * things _arguments has to execute at this place on the line (the
2527         * sub-contexts are used as tags).
2528         * The return value is particularly important here, it says if
2529         * there are arguments to completely at all. */
2530	{
2531	    LinkList descr, act, subc;
2532	    Caarg arg;
2533	    int ign = 0, ret = 1;
2534
2535	    descr = newlinklist();
2536	    act = newlinklist();
2537	    subc = newlinklist();
2538
2539	    while (lstate) {
2540		arg = lstate->def;
2541
2542		if (arg) {
2543		    ret = 0;
2544		    if (!ign && lstate->doff > 0) {
2545			ign = 1;
2546			ignore_prefix(lstate->doff);
2547		    }
2548		    ca_set_data(descr, act, subc, arg->opt, arg,
2549				lstate->curopt, (lstate->doff > 0));
2550		}
2551		lstate = lstate->snext;
2552	    }
2553	    if (!ret) {
2554		set_list_array(args[1], descr);
2555		set_list_array(args[2], act);
2556		set_list_array(args[3], subc);
2557	    }
2558	    return ret;
2559	}
2560    case 'O':
2561        /* This returns the descriptions for the options in the arrays whose
2562         * names are given as arguments.  The descriptions are strings in a
2563         * form usable by _describe.  The return value says if there are any
2564         * options to be completed. */
2565	{
2566	    LinkList next = newlinklist();
2567	    LinkList direct = newlinklist();
2568	    LinkList odirect = newlinklist();
2569	    LinkList equal = newlinklist(), l;
2570            LinkNode node;
2571	    Caopt p;
2572	    char *str;
2573	    int ret = 1;
2574
2575	    for (; lstate; lstate = lstate->snext) {
2576		if (lstate->actopts &&
2577		    (lstate->opt || (lstate->doff && lstate->def) ||
2578		     (lstate->def && lstate->def->opt &&
2579		      (lstate->def->type == CAA_OPT ||
2580		       (lstate->def->type >= CAA_RARGS &&
2581			lstate->def->num < 0)))) &&
2582		    (!lstate->def || lstate->def->type < CAA_RARGS ||
2583		     (lstate->def->type == CAA_RARGS ?
2584		      (lstate->curpos == lstate->argbeg + 1) :
2585		      (compcurrent == 1)))) {
2586		    ret = 0;
2587		    for (p = lstate->d->opts; p; p = p->next) {
2588			if (p->active && !p->not) {
2589			    switch (p->type) {
2590			    case CAO_NEXT:    l = next;    break;
2591			    case CAO_DIRECT:  l = direct;  break;
2592			    case CAO_ODIRECT: l = odirect; break;
2593			    default:          l = equal;   break;
2594			    }
2595			    if (p->descr) {
2596				char *n = bslashcolon(p->name);
2597				int len = strlen(n) + strlen(p->descr) + 2;
2598
2599				str = (char *) zhalloc(len);
2600				strcpy(str, n);
2601				strcat(str, ":");
2602				strcat(str, p->descr);
2603			    } else
2604				str = bslashcolon(p->name);
2605
2606                            for (node = firstnode(l); node; incnode(node))
2607                                if (!strcmp(str, (char *) getdata(node)))
2608                                    break;
2609
2610                            if (!node)
2611                                addlinknode(l, str);
2612			}
2613		    }
2614		}
2615	    }
2616	    if (!ret) {
2617		set_list_array(args[1], next);
2618		set_list_array(args[2], direct);
2619		set_list_array(args[3], odirect);
2620		set_list_array(args[4], equal);
2621
2622		return 0;
2623	    }
2624	    return (ca_laststate.singles ? 2 : 1);
2625	}
2626    case 'L':
2627        /* This tests if the beginning of the current word matches an option.
2628         * It is for cases like `./configure --pre=/<TAB>' which should
2629         * complete to `--prefix=/...'.  The options name isn't fully typed
2630         * and _arguments finds out that there is no option `--pre' and that
2631         * it should complete some argument to an option.  It then uses -L
2632         * to find the option the argument is for. */
2633	{
2634	    LinkList descr, act, subc;
2635	    Caopt opt;
2636	    int ret = 1;
2637
2638	    descr = newlinklist();
2639	    act = newlinklist();
2640	    subc = newlinklist();
2641
2642	    while (lstate) {
2643		opt = ca_get_opt(lstate->d, args[1], 1, NULL);
2644
2645		if (opt && opt->args) {
2646		    ret = 0;
2647		    ca_set_data(descr, act, subc, opt->name, opt->args, opt, 1);
2648		}
2649		lstate = lstate->snext;
2650	    }
2651	    if (!ret) {
2652		set_list_array(args[2], descr);
2653		set_list_array(args[3], act);
2654		set_list_array(args[4], subc);
2655	    }
2656	    return ret;
2657	}
2658    case 's':
2659        /* This returns zero if we are completing single letter options.
2660         * It also uses its argument as the name of a parameter and sets
2661         * that to a string describing the argument behaviour of the last
2662         * option in the current word so that we can get the auto-suffix
2663         * right. */
2664	for (; lstate; lstate = lstate->snext)
2665	    if (lstate->d->single && lstate->singles &&
2666		lstate->actopts
2667#if 0
2668                /* let's try without, for the -W option of _arguments */
2669                && lstate->opt
2670#endif
2671                ) {
2672		setsparam(args[1],
2673			  ztrdup((lstate->ddef && lstate->dopt) ?
2674				 (lstate->dopt->type == CAO_DIRECT ?
2675				  "direct" :
2676				  ((lstate->dopt->type == CAO_OEQUAL ||
2677				    lstate->dopt->type == CAO_EQUAL) ?
2678				   "equal" : "next")) : ""));
2679		return 0;
2680	    }
2681	return 1;
2682    case 'M':
2683        /* This returns the match specs defined for the set of specs we are
2684         * using.  Returned, as usual in a parameter whose name is given as
2685         * the argument. */
2686	setsparam(args[1], ztrdup(ca_laststate.d->match));
2687	return 0;
2688    case 'a':
2689        /* This just sets the return value.  To zero if there would be or
2690         * were any normal arguments to be completed.  Used to decide if
2691         * _arguments should say `no arguments' or `no more arguments'. */
2692	for (; lstate; lstate = lstate->snext)
2693	    if (lstate->d->args || lstate->d->rest)
2694		return 0;
2695	return 1;
2696    case 'W':
2697        /* This gets two parameter names as arguments.  The first is set to
2698         * the current word sans any option prefixes handled by comparguments.
2699         * The second parameter is set to an array containing the options on
2700         * the line and their arguments.  I.e. the stuff _arguments returns
2701         * to its caller in the `line' and `opt_args' parameters. */
2702	{
2703	    Castate s;
2704	    char **ret, **p;
2705	    LinkNode n;
2706	    LinkList *a;
2707	    Caopt o;
2708	    int num;
2709
2710	    for (num = 0, s = lstate; s; s = s->snext)
2711		num += countlinknodes(s->args);
2712
2713	    ret = p = zalloc((num + 1) * sizeof(char *));
2714
2715	    for (s = lstate; s; s = s->snext)
2716		for (n = firstnode(s->args); n; incnode(n))
2717		    *p++ = ztrdup((char *) getdata(n));
2718	    *p = NULL;
2719
2720	    setaparam(args[1], ret);
2721
2722	    for (num = 0, s = lstate; s; s = s->snext)
2723		for (o = s->d->opts, a = s->oargs; o; o = o->next, a++)
2724		    if (*a)
2725			num += 2;
2726
2727	    ret = p = zalloc((num + 1) * sizeof(char *));
2728
2729	    for (s = lstate; s; s = s->snext)
2730		for (o = s->d->opts, a = s->oargs; o; o = o->next, a++)
2731		    if (*a) {
2732			*p++ = (o->set ? tricat(o->set, o->name, "") :
2733				ztrdup(o->name));
2734			*p++ = ca_colonlist(*a);
2735		    }
2736	    *p = NULL;
2737
2738	    sethparam(args[2], ret);
2739	}
2740	return 0;
2741    case 'n':
2742	/*
2743	 * This returns the array index of the word where normal
2744	 * arguments began.  It uses optbeg rather than nargbeg
2745	 * (the value used when parsing) because nargbeg is assigned
2746	 * to optbeg in the returned value and nargbeg isn't
2747	 * used.
2748	 *
2749	 * -->PLEASE DON'T ASK<--
2750	 *
2751	 * Thank you.
2752	 */
2753	setiparam(args[1], (zlong)ca_laststate.optbeg + !isset(KSHARRAYS));
2754	return 0;
2755    }
2756    return 1;
2757}
2758
2759/* Help for `_values'. */
2760
2761typedef struct cvdef *Cvdef;
2762typedef struct cvval *Cvval;
2763
2764/* Definitions for _values. */
2765
2766struct cvdef {
2767    char *descr;		/* global description */
2768    int hassep;			/* multiple values allowed */
2769    char sep;			/* separator character */
2770    char argsep;                /* argument separator */
2771    Cvdef next;			/* next in cache */
2772    Cvval vals;			/* value definitions */
2773    char **defs;		/* original strings */
2774    int ndefs;			/* number of ... */
2775    int lastt;			/* last time used */
2776    int words;                  /* if to look at other words */
2777};
2778
2779/* One value definition. */
2780
2781struct cvval {
2782    Cvval next;
2783    char *name;			/* value name */
2784    char *descr;		/* description */
2785    char **xor;			/* xor-list */
2786    int type;			/* CVV_* below */
2787    Caarg arg;			/* argument definition */
2788    int active;			/* still allowed */
2789};
2790
2791#define CVV_NOARG 0
2792#define CVV_ARG   1
2793#define CVV_OPT   2
2794
2795/* Cache. */
2796
2797#define MAX_CVCACHE 8
2798static Cvdef cvdef_cache[MAX_CVCACHE];
2799
2800/* Memory stuff. */
2801
2802static void
2803freecvdef(Cvdef d)
2804{
2805    if (d) {
2806	Cvval p, n;
2807
2808	zsfree(d->descr);
2809	if (d->defs)
2810	    freearray(d->defs);
2811
2812	for (p = d->vals; p; p = n) {
2813	    n = p->next;
2814	    zsfree(p->name);
2815	    zsfree(p->descr);
2816	    if (p->xor)
2817		freearray(p->xor);
2818	    freecaargs(p->arg);
2819	    zfree(p, sizeof(*p));
2820	}
2821	zfree(d, sizeof(*d));
2822    }
2823}
2824
2825/* Parse option definitions. */
2826
2827static Cvdef
2828parse_cvdef(char *nam, char **args)
2829{
2830    Cvdef ret;
2831    Cvval val, *valp;
2832    Caarg arg;
2833    char **oargs = args, sep = '\0', asep = '=', *name, *descr, *p, *q, **xor, c;
2834    int xnum, multi, vtype, hassep = 0, words = 0;
2835
2836    while (args && args[0] && args[1] &&
2837           args[0][0] == '-' &&
2838           (args[0][1] == 's' || args[0][1] == 'S' || args[0][1] == 'w') &&
2839           !args[0][2]) {
2840
2841        if (args[0][1] == 's') {
2842            hassep = 1;
2843            sep = args[1][0];
2844            args += 2;
2845        } else if (args[0][1] == 'S') {
2846            asep = args[1][0];
2847            args += 2;
2848        } else {
2849            words = 1;
2850            args++;
2851        }
2852    }
2853    if (!args[0] || !args[1]) {
2854	zwarnnam(nam, "not enough arguments");
2855	return NULL;
2856    }
2857    descr = *args++;
2858
2859    ret = (Cvdef) zalloc(sizeof(*ret));
2860    ret->descr = ztrdup(descr);
2861    ret->hassep = hassep;
2862    ret->sep = sep;
2863    ret->argsep = asep;
2864    ret->next = NULL;
2865    ret->vals = NULL;
2866    ret->defs = zarrdup(oargs);
2867    ret->ndefs = arrlen(oargs);
2868    ret->lastt = time(0);
2869    ret->words = words;
2870
2871    for (valp = &(ret->vals); *args; args++) {
2872	int bs = 0;
2873	p = dupstring(*args);
2874	xnum = 0;
2875
2876	/* xor list? */
2877	if (*p == '(') {
2878	    LinkList list = newlinklist();
2879	    LinkNode node;
2880	    char **xp, sav;
2881
2882	    while (*p && *p != ')') {
2883		for (p++; inblank(*p); p++);
2884
2885		if (*p == ')')
2886		    break;
2887		for (q = p++; *p && *p != ')' && !inblank(*p); p++);
2888
2889		if (!*p)
2890		    break;
2891
2892		sav = *p;
2893		*p = '\0';
2894		addlinknode(list, dupstring(q));
2895		xnum++;
2896		*p = sav;
2897	    }
2898	    if (*p != ')') {
2899		freecvdef(ret);
2900		zwarnnam(nam, "invalid argument: %s", *args);
2901		return NULL;
2902	    }
2903	    xor = (char **) zalloc((xnum + 2) * sizeof(char *));
2904	    for (node = firstnode(list), xp = xor; node; incnode(node), xp++)
2905		*xp = ztrdup((char *) getdata(node));
2906	    xp[0] = xp[1] = NULL;
2907
2908	    p++;
2909	} else
2910	    xor = NULL;
2911
2912	/* More than once allowed? */
2913	if ((multi = (*p == '*')))
2914	    p++;
2915
2916	/* Skip option name. */
2917
2918	for (name = p; *p && *p != ':' && *p != '['; p++)
2919	    if (*p == '\\' && p[1])
2920		p++, bs = 1;
2921
2922	if (hassep && !sep && name + bs + 1 < p) {
2923	    freecvdef(ret);
2924	    zwarnnam(nam, "no multi-letter values with empty separator allowed");
2925	    return NULL;
2926	}
2927	/* Optional description? */
2928
2929	if ((c = *p) == '[') {
2930	    *p = '\0';
2931	    for (descr = ++p; *p && *p != ']'; p++)
2932		if (*p == '\\' && p[1])
2933		    p++;
2934
2935	    if (!*p) {
2936		freecvdef(ret);
2937		zwarnnam(nam, "invalid value definition: %s", *args);
2938		return NULL;
2939	    }
2940	    *p++ = '\0';
2941	    c = *p;
2942	} else {
2943	    *p = '\0';
2944	    descr = NULL;
2945	}
2946	if (c && c != ':') {
2947	    freecvdef(ret);
2948	    zwarnnam(nam, "invalid value definition: %s", *args);
2949	    return NULL;
2950	}
2951	/* Get argument? */
2952
2953	if (c == ':') {
2954	    if (hassep && !sep) {
2955		freecvdef(ret);
2956		zwarnnam(nam, "no value with argument with empty separator allowed");
2957		return NULL;
2958	    }
2959	    if (*++p == ':') {
2960		p++;
2961		vtype = CVV_OPT;
2962	    } else
2963		vtype = CVV_ARG;
2964	    arg = parse_caarg(0, 0, 0, 0, name, &p, NULL);
2965	} else {
2966	    vtype = CVV_NOARG;
2967	    arg = NULL;
2968	}
2969	if (!multi) {
2970	    if (!xor) {
2971		xor = (char **) zalloc(2 * sizeof(char *));
2972		xor[1] = NULL;
2973	    }
2974	    xor[xnum] = ztrdup(name);
2975	}
2976	*valp = val = (Cvval) zalloc(sizeof(*val));
2977	valp = &((*valp)->next);
2978
2979	val->next = NULL;
2980	val->name = ztrdup(name);
2981	val->descr = ztrdup(descr);
2982	val->xor = xor;
2983	val->type = vtype;
2984	val->arg = arg;
2985    }
2986    return ret;
2987}
2988
2989/* Get the definition from the cache or newly built. */
2990
2991static Cvdef
2992get_cvdef(char *nam, char **args)
2993{
2994    Cvdef *p, *min, new;
2995    int i, na = arrlen(args);
2996
2997    for (i = MAX_CVCACHE, p = cvdef_cache, min = NULL; *p && i--; p++)
2998	if (*p && na == (*p)->ndefs && arrcmp(args, (*p)->defs)) {
2999	    (*p)->lastt = time(0);
3000
3001	    return *p;
3002	} else if (!min || !*p || (*p)->lastt < (*min)->lastt)
3003	    min = p;
3004    if (i > 0)
3005	min = p;
3006    if ((new = parse_cvdef(nam, args))) {
3007	freecvdef(*min);
3008	*min = new;
3009    }
3010    return new;
3011}
3012
3013/* Get the definition for a value. */
3014
3015static Cvval
3016cv_get_val(Cvdef d, char *name)
3017{
3018    Cvval p;
3019
3020    for (p = d->vals; p; p = p->next)
3021	if (!strcmp(name, p->name))
3022	    return p;
3023
3024    return NULL;
3025}
3026
3027static Cvval
3028cv_quote_get_val(Cvdef d, char *name)
3029{
3030    int ne;
3031
3032    /* remove quotes */
3033    name = dupstring(name);
3034    ne = noerrs;
3035    noerrs = 2;
3036    parse_subst_string(name);
3037    noerrs = ne;
3038    remnulargs(name);
3039    untokenize(name);
3040
3041    return cv_get_val(d, name);
3042}
3043
3044/* Handle a xor list. */
3045
3046static void
3047cv_inactive(Cvdef d, char **xor)
3048{
3049    if (xor) {
3050	Cvval val;
3051
3052	for (; *xor; xor++)
3053	    if ((val = cv_get_val(d, *xor)))
3054		val->active = 0;
3055    }
3056}
3057
3058/* Parse state. */
3059
3060struct cvstate {
3061    Cvdef d;
3062    Caarg def;
3063    Cvval val;
3064    LinkList vals;
3065};
3066
3067static struct cvstate cv_laststate;
3068static int cv_parsed = 0, cv_alloced = 0;
3069
3070/* Get the next value in the string.  Return it's definition and update the
3071 * sp pointer to point to the end of the value (plus argument, if any).
3072 * If there is no next value, the string pointer is set to null.  In any
3073 * case ap will point to the beginning of the argument or will be a null
3074 * pointer if there is no argument.
3075 */
3076
3077static Cvval
3078cv_next(Cvdef d, char **sp, char **ap)
3079{
3080    Cvval r = NULL;
3081    char *s = *sp;
3082
3083    if (!*s) {
3084        *sp = *ap = NULL;
3085
3086        return NULL;
3087    }
3088    if ((d->hassep && !d->sep) || !d->argsep) {
3089        char sav, ec, *v = s, *os;
3090
3091        ec = ((d->hassep && d->sep) ? d->sep : d->argsep);
3092
3093        do {
3094            sav = *++s;
3095            *s = '\0';
3096            if ((r = cv_quote_get_val(d, v))) {
3097                *s = sav;
3098
3099                break;
3100            }
3101            *s = sav;
3102        } while (*s && *s != ec);
3103
3104        os = s;
3105
3106        if (d->hassep && d->sep) {
3107            if ((s = strchr(s, d->sep)))
3108                *sp = s + 1;
3109            else
3110                *sp = NULL;
3111        } else
3112            *sp = s;
3113        if (d->argsep && *os == d->argsep) {
3114            *ap = os + 1;
3115            *sp = NULL;
3116        } else if (r && r->type != CVV_NOARG)
3117            *ap = os;
3118        else
3119            *ap = NULL;
3120
3121        return r;
3122
3123    } else if (d->hassep) {
3124        char *ns = strchr(s, d->sep), *as = 0, *sap, sav = 0;
3125        int skip = 0;
3126
3127        if (d->argsep && (as = strchr(s, d->argsep)) && (!ns || as <= ns)) {
3128            *ap = as + 1;
3129            ns = strchr(as + 1, d->sep);
3130            skip = 1;
3131            sap = as;
3132        } else {
3133            *ap = NULL;
3134            sap = ns;
3135        }
3136        if (sap) {
3137            sav = *sap;
3138            *sap = '\0';
3139        }
3140        if ((!(r = cv_quote_get_val(d, s)) || r->type == CVV_NOARG) && skip)
3141            ns = as;
3142
3143        if (sap)
3144            *sap = sav;
3145
3146        *sp = ((!ns || (ns == as && r && r->type != CVV_NOARG)) ? NULL : ns + 1);
3147
3148        return r;
3149    } else {
3150        char *as = strchr(s, d->argsep), *sap, sav = 0;
3151
3152        *sp = NULL;
3153
3154        if (as) {
3155            *ap = as + 1;
3156            sap = as;
3157            sav = *as;
3158            *sap = '\0';
3159        } else
3160            *ap = sap = NULL;
3161
3162        r = cv_quote_get_val(d, s);
3163
3164        if (sap)
3165            *sap = sav;
3166
3167        return r;
3168    }
3169}
3170
3171/* Parse the current word. */
3172
3173static void
3174cv_parse_word(Cvdef d)
3175{
3176    Cvval val;
3177    struct cvstate state;
3178    char *str, *arg = NULL, *pign = compprefix;
3179    int nosfx = 0;
3180
3181    if (cv_alloced)
3182	freelinklist(cv_laststate.vals, freestr);
3183
3184    for (val = d->vals; val; val = val->next)
3185	val->active = 1;
3186
3187    state.d = d;
3188    state.def = NULL;
3189    state.val = NULL;
3190    state.vals = (LinkList) znewlinklist();
3191
3192    cv_alloced = 1;
3193
3194    if (d->words && compwords[0]) {
3195        int i;
3196
3197        for (i = 1; compwords[i]; i++)
3198            if (i != compcurrent - 1)
3199                for (str = compwords[i]; str && *str; ) {
3200                    if ((val = cv_next(d, &str, &arg))) {
3201                        zaddlinknode(state.vals, ztrdup(val->name));
3202                        if (arg) {
3203                            char sav = '\0';
3204
3205                            if (str) {
3206                                sav = str[-1];
3207                                str[-1] = '\0';
3208                            }
3209                            zaddlinknode(state.vals, ztrdup(arg));
3210                            if (str)
3211                                str[-1] = sav;
3212                        } else
3213                            zaddlinknode(state.vals, ztrdup(""));
3214
3215                        if (i + 1 < compcurrent)
3216                            cv_inactive(d, val->xor);
3217                    }
3218                }
3219
3220        val = NULL;
3221        arg = NULL;
3222    }
3223    for (str = compprefix; str && *str; ) {
3224        if ((val = cv_next(d, &str, &arg))) {
3225            zaddlinknode(state.vals, ztrdup(val->name));
3226            if (arg) {
3227                if (str) {
3228                    char sav = str[-1];
3229
3230                    str[-1] = '\0';
3231                    zaddlinknode(state.vals, ztrdup(arg));
3232                    str[-1] = sav;
3233                } else {
3234                    zaddlinknode(state.vals, tricat(arg, compsuffix, ""));
3235                    nosfx = 1;
3236                }
3237            } else
3238                zaddlinknode(state.vals, ztrdup(""));
3239
3240            cv_inactive(d, val->xor);
3241
3242            if (str)
3243                pign = str;
3244            else
3245                val->active = 1;
3246        }
3247    }
3248    state.val = val;
3249    if (val && arg && !str)
3250        state.def = val->arg;
3251
3252    if (!nosfx && d->hassep) {
3253        int ign = 0;
3254        char *more = NULL;
3255
3256        ignore_prefix(pign - compprefix);
3257
3258        if (!d->sep && (!val || val->type == CVV_NOARG)) {
3259            ign = strlen(compsuffix);
3260            more = compsuffix;
3261        } else {
3262            if (d->sep) {
3263                char *ns = strchr(compsuffix, d->sep), *as;
3264
3265                if (d->argsep && (as = strchr(compsuffix, d->argsep)) &&
3266                    (!ns || as <= ns)) {
3267                    ign = strlen(as);
3268                } else
3269                    ign = (ns ? strlen(ns) : 0);
3270
3271                more = (ns ? ns + 1 : NULL);
3272            } else if (d->argsep) {
3273                char *as;
3274
3275                if ((as = strchr(compsuffix, d->argsep)))
3276                    ign = strlen(as);
3277            }
3278        }
3279        more = dupstring(more);
3280
3281        if (ign)
3282            ignore_suffix(ign);
3283
3284        while (more && *more) {
3285            if ((val = cv_next(d, &more, &arg))) {
3286                zaddlinknode(state.vals, ztrdup(val->name));
3287                if (arg) {
3288                    if (more) {
3289                        char sav = more[-1];
3290
3291                        more[-1] = '\0';
3292                        zaddlinknode(state.vals, ztrdup(arg));
3293                        more[-1] = sav;
3294                    } else {
3295                        zaddlinknode(state.vals, tricat(arg, compsuffix, ""));
3296                        nosfx = 1;
3297                    }
3298                } else
3299                    zaddlinknode(state.vals, ztrdup(""));
3300
3301                cv_inactive(d, val->xor);
3302            }
3303        }
3304    } else if (arg)
3305        ignore_prefix(arg - compprefix);
3306    else
3307        ignore_prefix(pign - compprefix);
3308
3309    memcpy(&cv_laststate, &state, sizeof(state));
3310}
3311
3312static int
3313bin_compvalues(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
3314{
3315    int min, max, n;
3316
3317    if (incompfunc != 1) {
3318	zwarnnam(nam, "can only be called from completion function");
3319	return 1;
3320    }
3321    if (args[0][0] != '-' || !args[0][1] || args[0][2]) {
3322	zwarnnam(nam, "invalid argument: %s", args[0]);
3323	return 1;
3324    }
3325    if (args[0][1] != 'i' && !cv_parsed) {
3326	zwarnnam(nam, "no parsed state");
3327	return 1;
3328    }
3329    switch (args[0][1]) {
3330    case 'i': min = 2; max = -1; break;
3331    case 'D': min = 2; max =  2; break;
3332    case 'C': min = 1; max =  1; break;
3333    case 'V': min = 3; max =  3; break;
3334    case 's': min = 1; max =  1; break;
3335    case 'S': min = 1; max =  1; break;
3336    case 'd': min = 1; max =  1; break;
3337    case 'L': min = 3; max =  4; break;
3338    case 'v': min = 1; max =  1; break;
3339    default:
3340	zwarnnam(nam, "invalid option: %s", args[0]);
3341	return 1;
3342    }
3343    n = arrlen(args) - 1;
3344    if (n < min) {
3345	zwarnnam(nam, "not enough arguments");
3346	return 1;
3347    } else if (max >= 0 && n > max) {
3348	zwarnnam(nam, "too many arguments");
3349	return 1;
3350    }
3351    switch (args[0][1]) {
3352    case 'i':
3353        /* This initialises the internal data structures.  The arguments are
3354         * just the arguments that were given to _values itself. */
3355	{
3356	    Cvdef def = get_cvdef(nam, args + 1);
3357	    int cvp = cv_parsed;
3358
3359	    cv_parsed = 0;
3360
3361	    if (!def)
3362		return 1;
3363
3364	    cv_parsed = cvp;
3365	    cv_parse_word(def);
3366	    cv_parsed = 1;
3367
3368	    return 0;
3369	}
3370
3371    case 'D':
3372        /* This returns the description and action to use if we are at
3373         * a place where some action has to be used at all.  In that case
3374         * zero is returned and non-zero otherwise. */
3375	{
3376	    Caarg arg = cv_laststate.def;
3377
3378	    if (arg) {
3379		setsparam(args[1], ztrdup(arg->descr));
3380		setsparam(args[2], ztrdup(arg->action));
3381
3382		return 0;
3383	    }
3384	    return 1;
3385	}
3386    case 'C':
3387        /* This returns the sub-context (i.e.: the tag) to use when executing
3388         * an action. */
3389	{
3390	    Caarg arg = cv_laststate.def;
3391
3392	    if (arg) {
3393		setsparam(args[1], ztrdup(arg->opt));
3394
3395		return 0;
3396	    }
3397	    return 1;
3398	}
3399    case 'V':
3400        /* This is what -O is for comparguments: it returns (in three arrays)
3401         * the values for values without arguments, with arguments and with
3402         * optional arguments (so that we can get the auto-suffixes right).
3403         * As for comparguments, the strings returned are usable for _describe. */
3404	{
3405	    LinkList noarg = newlinklist();
3406	    LinkList arg = newlinklist();
3407	    LinkList opt = newlinklist(), l;
3408	    Cvval p;
3409	    char *str;
3410
3411	    for (p = cv_laststate.d->vals; p; p = p->next) {
3412		if (p->active) {
3413		    switch (p->type) {
3414		    case CVV_NOARG: l = noarg; break;
3415		    case CVV_ARG:   l = arg;   break;
3416		    default:        l = opt;   break;
3417		    }
3418		    if (p->descr) {
3419			int len = strlen(p->name) + strlen(p->descr) + 2;
3420
3421			str = (char *) zhalloc(len);
3422			strcpy(str, p->name);
3423			strcat(str, ":");
3424			strcat(str, p->descr);
3425		    } else
3426			str = p->name;
3427		    addlinknode(l, str);
3428		}
3429	    }
3430	    set_list_array(args[1], noarg);
3431	    set_list_array(args[2], arg);
3432	    set_list_array(args[3], opt);
3433
3434	    return 0;
3435	}
3436    case 's':
3437        /* This returns the value separator, if any, and sets the return
3438         * value to say if there is such a separator. */
3439	if (cv_laststate.d->hassep) {
3440	    char tmp[2];
3441
3442	    tmp[0] = cv_laststate.d->sep;
3443	    tmp[1] = '\0';
3444	    setsparam(args[1], ztrdup(tmp));
3445
3446	    return 0;
3447	}
3448	return 1;
3449    case 'S':
3450        /* Like -s, but for the separator between values and their arguments. */
3451	{
3452	    char tmp[2];
3453
3454	    tmp[0] = cv_laststate.d->argsep;
3455	    tmp[1] = '\0';
3456	    setsparam(args[1], ztrdup(tmp));
3457	}
3458	return 0;
3459    case 'd':
3460        /* This returns the description string (first argument to _values)
3461         * which is passed down to _describe. */
3462	setsparam(args[1], ztrdup(cv_laststate.d->descr));
3463	return 0;
3464    case 'L':
3465        /* Almost the same as for comparguments.  This gets a value name
3466         * and returns the description and action of its first argument, if
3467         * any.  The rest (prefix matching) is in _values.  Return non-zero
3468         * if there is no such option. */
3469	{
3470	    Cvval val = cv_get_val(cv_laststate.d, args[1]);
3471
3472	    if (val && val->arg) {
3473		setsparam(args[2], val->arg->descr);
3474		setsparam(args[3], val->arg->action);
3475
3476		if (args[4])
3477		    setsparam(args[4], ztrdup(val->name));
3478
3479		return 0;
3480	    }
3481	    return 1;
3482	}
3483    case 'v':
3484        /* Again, as for comparguments.  This returns the values and their
3485         * arguments as an array which will be stored in val_args in _values. */
3486	if (cv_laststate.vals) {
3487	    char **ret;
3488
3489	    ret = zlinklist2array(cv_laststate.vals);
3490	    sethparam(args[1], ret);
3491
3492	    return 0;
3493	}
3494	return 1;
3495    }
3496    return 1;
3497}
3498
3499static char *
3500comp_quote(char *str, int prefix)
3501{
3502    int x;
3503    char *ret;
3504
3505    if ((x = (prefix && *str == '=')))
3506	*str = 'x';
3507
3508    ret = quotestring(str, NULL, *compqstack);
3509
3510    if (x)
3511	*str = *ret = '=';
3512
3513    return ret;
3514}
3515
3516static int
3517bin_compquote(char *nam, char **args, Options ops, UNUSED(int func))
3518{
3519    char *name;
3520    struct value vbuf;
3521    Value v;
3522
3523    if (incompfunc != 1) {
3524	zwarnnam(nam, "can only be called from completion function");
3525	return 1;
3526    }
3527    /* Anything to do? */
3528
3529    if (!compqstack || !*compqstack)
3530	return 0;
3531
3532    /* For all parameters given... */
3533
3534    while ((name = *args++)) {
3535	name = dupstring(name);
3536	queue_signals();
3537	if ((v = getvalue(&vbuf, &name, 0))) {
3538	    switch (PM_TYPE(v->pm->node.flags)) {
3539	    case PM_SCALAR:
3540		setstrvalue(v, ztrdup(comp_quote(getstrvalue(v),
3541						 OPT_ISSET(ops,'p'))));
3542		break;
3543	    case PM_ARRAY:
3544		{
3545		    char **val = v->pm->gsu.a->getfn(v->pm);
3546		    char **new = (char **) zalloc((arrlen(val) + 1) *
3547						  sizeof(char *));
3548		    char **p = new;
3549
3550		    for (; *val; val++, p++)
3551			*p = ztrdup(comp_quote(*val, OPT_ISSET(ops,'p')));
3552		    *p = NULL;
3553
3554		    setarrvalue(v, new);
3555		}
3556		break;
3557	    default:
3558		zwarnnam(nam, "invalid parameter type: %s", args[-1]);
3559	    }
3560	} else
3561	    zwarnnam(nam, "unknown parameter: %s", args[-1]);
3562	unqueue_signals();
3563    }
3564    return 0;
3565}
3566
3567/* Tags stuff. */
3568
3569typedef struct ctags *Ctags;
3570typedef struct ctset *Ctset;
3571
3572/* A bunch of tag sets. */
3573
3574struct ctags {
3575    char **all;			/* all tags offered */
3576    char *context;		/* the current context */
3577    int init;			/* not yet used */
3578    Ctset sets;			/* the tag sets */
3579};
3580
3581/* A tag set. */
3582
3583struct ctset {
3584    Ctset next;
3585    char **tags;		/* the tags */
3586    char *tag;			/* last tag checked for -A */
3587    char **ptr;			/* ptr into tags for -A */
3588};
3589
3590/* Array of tag-set infos. Index is the locallevel. */
3591
3592#define MAX_TAGS 256
3593static Ctags comptags[MAX_TAGS];
3594
3595/* locallevel at last comptags -i */
3596
3597static int lasttaglevel;
3598
3599static void
3600freectset(Ctset s)
3601{
3602    Ctset n;
3603
3604    while (s) {
3605	n = s->next;
3606
3607	if (s->tags)
3608	    freearray(s->tags);
3609	zsfree(s->tag);
3610	zfree(s, sizeof(*s));
3611
3612	s = n;
3613    }
3614}
3615
3616static void
3617freectags(Ctags t)
3618{
3619    if (t) {
3620	if (t->all)
3621	    freearray(t->all);
3622	zsfree(t->context);
3623	freectset(t->sets);
3624	zfree(t, sizeof(*t));
3625    }
3626}
3627
3628/* Set the tags for the current local level. */
3629
3630static void
3631settags(int level, char **tags)
3632{
3633    Ctags t;
3634
3635    if (comptags[level])
3636	freectags(comptags[level]);
3637
3638    comptags[level] = t = (Ctags) zalloc(sizeof(*t));
3639
3640    t->all = zarrdup(tags + 1);
3641    t->context = ztrdup(*tags);
3642    t->sets = NULL;
3643    t->init = 1;
3644}
3645
3646/* Check if an array contains a string. */
3647
3648/**/
3649static int
3650arrcontains(char **a, char *s, int colon)
3651{
3652    char *p, *q;
3653
3654    while (*a) {
3655	if (colon) {
3656	    for (p = s, q = *a++; *p && *q && *p != ':' && *q != ':'; p++, q++)
3657		if (*p != *q)
3658		    break;
3659	    if ((!*p || *p == ':') && (!*q || *q == ':'))
3660		return 1;
3661	} else if (!strcmp(*a++, s))
3662	    return 1;
3663    }
3664    return 0;
3665}
3666
3667static int
3668bin_comptags(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
3669{
3670    int min, max, n, level;
3671
3672    if (incompfunc != 1) {
3673	zwarnnam(nam, "can only be called from completion function");
3674	return 1;
3675    }
3676    if (args[0][0] != '-' || !args[0][1] ||
3677	(args[0][2] && (args[0][2] != '-' || args[0][3]))) {
3678	zwarnnam(nam, "invalid argument: %s", args[0]);
3679	return 1;
3680    }
3681    level = locallevel - (args[0][2] ? 1 : 0);
3682    if (level >= MAX_TAGS) {
3683	zwarnnam(nam, "nesting level too deep");
3684	return 1;
3685    }
3686    if (args[0][1] != 'i' && args[0][1] != 'I' && !comptags[level]) {
3687	zwarnnam(nam, "no tags registered");
3688	return 1;
3689    }
3690    switch (args[0][1]) {
3691    case 'i': min = 2; max = -1; break;
3692    case 'C': min = 1; max =  1; break;
3693    case 'T': min = 0; max =  0; break;
3694    case 'N': min = 0; max =  0; break;
3695    case 'R': min = 1; max =  1; break;
3696    case 'S': min = 1; max =  1; break;
3697    case 'A': min = 2; max =  3; break;
3698    default:
3699	zwarnnam(nam, "invalid option: %s", args[0]);
3700	return 1;
3701    }
3702    n = arrlen(args) - 1;
3703    if (n < min) {
3704	zwarnnam(nam, "not enough arguments");
3705	return 1;
3706    } else if (max >= 0 && n > max) {
3707	zwarnnam(nam, "too many arguments");
3708	return 1;
3709    }
3710    switch (args[0][1]) {
3711    case 'i':
3712	settags(level, args + 1);
3713	lasttaglevel = level;
3714	break;
3715    case 'C':
3716	setsparam(args[1], ztrdup(comptags[level]->context));
3717	break;
3718    case 'T':
3719	return !comptags[level]->sets;
3720    case 'N':
3721	{
3722	    Ctset s;
3723
3724	    if (comptags[level]->init)
3725		comptags[level]->init = 0;
3726	    else if ((s = comptags[level]->sets)) {
3727		comptags[level]->sets = s->next;
3728		s->next = NULL;
3729		freectset(s);
3730	    }
3731	    return !comptags[level]->sets;
3732	}
3733    case 'R':
3734	{
3735	    Ctset s;
3736
3737	    return !((s = comptags[level]->sets) &&
3738		     arrcontains(s->tags, args[1], 1));
3739	}
3740    case 'A':
3741	{
3742	    Ctset s;
3743
3744	    if (comptags[level] && (s = comptags[level]->sets)) {
3745		char **q, *v = NULL;
3746		int l = strlen(args[1]);
3747
3748		if (!s->tag || strcmp(s->tag, args[1])) {
3749		    zsfree(s->tag);
3750		    s->tag = ztrdup(args[1]);
3751		    s->ptr = s->tags;
3752		}
3753		for (q = s->ptr; *q; q++) {
3754		    if (strpfx(args[1], *q)) {
3755			if (!(*q)[l]) {
3756			    v = *q;
3757			    break;
3758			} else if ((*q)[l] == ':') {
3759			    v = (*q) + l + 1;
3760			    break;
3761			}
3762		    }
3763		}
3764		if (!v) {
3765		    zsfree(s->tag);
3766		    s->tag = NULL;
3767		    return 1;
3768		}
3769		s->ptr = q + 1;
3770		setsparam(args[2], ztrdup(*v == '-' ? dyncat(args[1], v) : v));
3771		if (args[3]) {
3772		    char *r = dupstring(*q), *p;
3773
3774		    for (p = r + (v - *q); *p && *p != ':'; p++);
3775		    *p = '\0';
3776
3777		    setsparam(args[3], ztrdup(r));
3778		}
3779		return 0;
3780	    }
3781	    return 1;
3782	}
3783    case 'S':
3784	if (comptags[level]->sets) {
3785	    char **ret;
3786
3787	    ret = zarrdup(comptags[level]->sets->tags);
3788	    setaparam(args[1], ret);
3789	} else
3790	    return 1;
3791
3792	break;
3793    }
3794    return 0;
3795}
3796
3797static int
3798bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
3799{
3800    if (incompfunc != 1) {
3801	zwarnnam(nam, "can only be called from completion function");
3802	return 1;
3803    }
3804    if (!lasttaglevel || !comptags[lasttaglevel]) {
3805	zwarnnam(nam, "no tags registered");
3806	return 1;
3807    }
3808    if (*args) {
3809	if (!strcmp(*args, "-m")) {
3810	    char *s, *p, *q, *c, **all = comptags[lasttaglevel]->all;
3811	    LinkList list = newlinklist();
3812	    int num = 0;
3813	    Ctset set;
3814
3815	    while ((s = *++args)) {
3816		while (*s) {
3817		    while (*s && iblank(*s))
3818			s++;
3819		    for (p = q = s, c = NULL; *s && !inblank(*s); s++) {
3820			if (!c && *s == ':')
3821			    c = p;
3822			if (*s == '\\' && s[1])
3823			    s++;
3824			*p++ = *s;
3825		    }
3826		    if (*s)
3827			s++;
3828		    *p = '\0';
3829		    if (*q) {
3830			char *qq, *qqq;
3831
3832			if (c)
3833			    *c = '\0';
3834
3835			qqq = qq = dupstring(q);
3836			while (*qqq) {
3837			    if (*qqq == '\\' && qqq[1])
3838				qqq++;
3839			    else if (*qqq == '{')
3840				*qqq = Inbrace;
3841			    else if (*qqq == '}')
3842				*qqq = Outbrace;
3843			    else if (*qqq == ',')
3844				*qqq = Comma;
3845			    qqq++;
3846			}
3847			tokenize(qq);
3848			if (haswilds(qq) || hasbraces(qq)) {
3849			    Patprog prog;
3850			    LinkNode bnode, node;
3851			    LinkList blist = newlinklist();
3852
3853			    addlinknode(blist, qq);
3854			    for (bnode = firstnode(blist); bnode; incnode(bnode))
3855				while (hasbraces(getdata(bnode)))
3856				    xpandbraces(blist, &bnode);
3857
3858			    for (bnode = firstnode(blist); bnode; incnode(bnode)) {
3859				qq = (char *) getdata(bnode);
3860				if ((prog = patcompile(qq, PAT_STATIC, NULL))) {
3861				    char **a, *n;
3862				    int l = (c ? strlen(c + 1) + 2 : 1), al;
3863
3864				    for (a = all; *a; a++) {
3865					for (node = firstnode(list); node;
3866					     incnode(node)) {
3867					    char *as, *ls;
3868
3869					    for (as = *a, ls = (char *) getdata(node);
3870						 *as && *ls && *ls != ':'; as++, ls++)
3871						if (*as != *ls)
3872						    break;
3873					    if (!*as && (!*ls || *ls == ':'))
3874						break;
3875					}
3876					if (node)
3877					    continue;
3878					if (pattry(prog, *a)) {
3879					    n = (char *) zhalloc((al = strlen(*a)) + l);
3880					    strcpy(n, *a);
3881					    if (c) {
3882						n[al] = ':';
3883						strcpy(n + al + 1, c + 1);
3884					    }
3885					    addlinknode(list, n);
3886					    num++;
3887					}
3888				    }
3889				}
3890			    }
3891			} else if (arrcontains(all, q, 0)) {
3892			    for (set = comptags[lasttaglevel]->sets; set;
3893				 set = set->next)
3894				if (arrcontains(set->tags, q, 0))
3895				    break;
3896			    if (!set) {
3897				addlinknode(list, q);
3898				num++;
3899			    }
3900			}
3901			if (c)
3902			    *c = ':';
3903		    }
3904		}
3905		if (num) {
3906		    Ctset l;
3907
3908		    set = (Ctset) zalloc(sizeof(*set));
3909
3910		    set->tags = zlinklist2array(list);
3911		    set->next = NULL;
3912		    set->ptr = NULL;
3913		    set->tag = NULL;
3914
3915		    if ((l = comptags[lasttaglevel]->sets)) {
3916			while (l->next)
3917			    l = l->next;
3918
3919			l->next = set;
3920		    } else
3921			comptags[lasttaglevel]->sets = set;
3922		}
3923	    }
3924	} else {
3925	    char **p, **q, **all;
3926	    int sep = 0;
3927
3928	    if ((sep = !strcmp(*args, "-s")))
3929		args++;
3930
3931	    for (p = q = args, all = comptags[lasttaglevel]->all; *p; p++)
3932		if (arrcontains(all, *p, 1)) {
3933		    Ctset s;
3934
3935		    for (s = comptags[lasttaglevel]->sets; s; s = s->next)
3936			if (arrcontains(s->tags, *p, 0))
3937			    break;
3938
3939		    if (!s)
3940			*q++ = *p;
3941		}
3942	    *q = NULL;
3943
3944	    if (*args) {
3945		char *dummy[2];
3946
3947		do {
3948		    Ctset s = (Ctset) zalloc(sizeof(*s)), l;
3949
3950		    if (sep) {
3951			dummy[0] = *args++;
3952			dummy[1] = NULL;
3953			s->tags = zarrdup(dummy);
3954		    } else
3955			s->tags = zarrdup(args);
3956		    s->next = NULL;
3957		    s->ptr = NULL;
3958		    s->tag = NULL;
3959
3960		    if ((l = comptags[lasttaglevel]->sets)) {
3961			while (l->next)
3962			    l = l->next;
3963
3964			l->next = s;
3965		    } else
3966			comptags[lasttaglevel]->sets = s;
3967		} while (sep && *args);
3968	    }
3969	}
3970    }
3971    return 0;
3972}
3973
3974#define PATH_MAX2 (PATH_MAX * 2)
3975
3976/*
3977 * Return a list of files we should accept exactly, without
3978 * trying pattern matching.
3979 *
3980 * This is based on the accept-exact style, which may be
3981 * an array so is passed in via "accept".  The trial files
3982 * are input in "names".  "skipped" is passed down straight
3983 * from the file completion function:  it's got something to
3984 * do with other components in the path but it's hard to work out
3985 * quite what.
3986 *
3987 * There is one extra trick here for Cygwin.  Regardless of the style,
3988 * if the file ends in a colon it has to be a drive or a special device
3989 * file and we always accept it exactly because treating it as a pattern
3990 * won't work.
3991 */
3992static LinkList
3993cfp_test_exact(LinkList names, char **accept, char *skipped)
3994{
3995    char buf[PATH_MAX2 + 1], *suf, *p;
3996    int l, sl, found = 0;
3997    struct stat st;
3998    LinkNode node;
3999    LinkList ret = newlinklist(), alist = NULL;
4000#ifdef __CYGWIN__
4001    int accept_off = 0;
4002#endif
4003
4004    /*
4005     * Don't do this unless completion has provided either a
4006     * prefix or suffix from the command line.
4007     */
4008    if (!(compprefix && *compprefix) && !(compsuffix && *compsuffix))
4009	return NULL;
4010
4011    /*
4012     * See if accept-exact is off, implicitly or explicitly.
4013     */
4014    if (!accept || !*accept ||
4015	((!strcmp(*accept, "false") || !strcmp(*accept, "no") ||
4016	  !strcmp(*accept, "off") || !strcmp(*accept, "0")) && !accept[1])) {
4017#ifdef __CYGWIN__
4018	accept_off = 1;
4019#else
4020	/* If not Cygwin, nothing to do here. */
4021	return NULL;
4022#endif
4023    }
4024
4025    /*
4026     * See if the style is something other than just a boolean.
4027     */
4028    if (
4029#ifdef __CYGWIN__
4030	!accept_off &&
4031#endif
4032	(accept[1] ||
4033	 (strcmp(*accept, "true") && strcmp(*accept, "yes") &&
4034	  strcmp(*accept, "on") && strcmp(*accept, "1")))) {
4035	Patprog prog;
4036
4037	alist = newlinklist();
4038
4039	for (; (p = *accept); accept++) {
4040	    if (*p == '*' && !p[1]) {
4041		alist = NULL;
4042		break;
4043	    }
4044	    tokenize(p = dupstring(p));
4045	    if ((prog = patcompile(p, 0, NULL)))
4046		addlinknode(alist, prog);
4047	}
4048    }
4049    /*
4050     * Assemble the bits other than the set of file names:
4051     * the other components, and the prefix and suffix.
4052     */
4053    sl = strlen(skipped) + (compprefix ? strlen(compprefix) : 0) +
4054	(compsuffix ? strlen(compsuffix) : 0);
4055
4056    if (sl > PATH_MAX2)
4057	return NULL;
4058
4059    suf = dyncat(skipped, rembslash(dyncat(compprefix, compsuffix)));
4060
4061    for (node = firstnode(names); node; incnode(node)) {
4062	l = strlen(p = (char *) getdata(node));
4063	if (l + sl < PATH_MAX2) {
4064#ifdef __CYGWIN__
4065	    char *testbuf;
4066#define TESTBUF testbuf
4067#else
4068#define TESTBUF buf
4069#endif
4070	    strcpy(buf, p);
4071	    strcpy(buf + l, suf);
4072#ifdef __CYGWIN__
4073	    if (accept_off) {
4074		int sl = strlen(buf);
4075		/*
4076		 * If accept-exact is not set, accept this only if
4077		 * it looks like a special file such as a drive.
4078		 * We still test if it exists.
4079		 */
4080		if (!sl || strchr(buf, '/') || buf[sl-1] != ':')
4081		    continue;
4082		if (sl == 2) {
4083		    /*
4084		     * Recent versions of Cygwin only recognise "c:/",
4085		     * but not "c:", as special directories.  So
4086		     * we have to append the slash for the purpose of
4087		     * the test.
4088		     */
4089		    testbuf = zhalloc(sl + 2);
4090		    strcpy(testbuf, buf);
4091		    testbuf[sl] = '/';
4092		    testbuf[sl+1] = '\0';
4093		} else {
4094		    /* Don't do this with stuff like PRN: */
4095		    testbuf = buf;
4096		}
4097	    } else {
4098		testbuf = buf;
4099	    }
4100#endif
4101	    if (!ztat(TESTBUF, &st, 0)) {
4102		/*
4103		 * File exists; if accept-exact contained non-boolean
4104		 * values it must match those, too.
4105		 */
4106		if (alist) {
4107		    LinkNode anode;
4108
4109		    for (anode = firstnode(alist); anode; incnode(anode))
4110			if (pattry((Patprog) getdata(anode), buf))
4111			    break;
4112
4113		    if (!anode)
4114			continue;
4115		}
4116		found = 1;
4117		addlinknode(ret, dupstring(buf));
4118	    }
4119	}
4120    }
4121    return (found ? ret : NULL);
4122}
4123
4124
4125/*
4126 * This code constructs (from heap) and returns a string that
4127 * corresponds to a series of matches; when compiled as a pattern, at
4128 * each position it matches either the character from the string "add"
4129 * or the corresponding single-character match from the set of matchers.
4130 * To take a simple case, if add is "a" and the single matcher for the
4131 * character position matches "[0-9]", the pattern returned is "[0-9a]".
4132 * We take account of equivalences between the word and line, too.
4133 *
4134 * As there are virtually no comments in this file, I don't really
4135 * know why we're doing this, but it's to do with a matcher which
4136 * is passed as an argument to the utility compfiles -p/-P.
4137 */
4138static char *
4139cfp_matcher_range(Cmatcher *ms, char *add)
4140{
4141    Cmatcher *mp, m;
4142    int len = 0, mt;
4143    char *ret = NULL, *p = NULL, *adds = add;
4144
4145    /*
4146     * Do this twice:  once to work out the length of the
4147     * string in len, the second time to build it in ret.
4148     * This is probably worthwhile because otherwise memory
4149     * management is difficult.
4150     */
4151    for (;;) {
4152	MB_METACHARINIT();
4153	for (mp = ms; *add; ) {
4154	    convchar_t addc;
4155	    int addlen;
4156
4157	    addlen = MB_METACHARLENCONV(add, &addc);
4158#ifdef MULTIBYTE_SUPPORT
4159	    if (addc == WEOF)
4160		addc = (wchar_t)(*p == Meta ? p[1] ^ 32 : *p);
4161#endif
4162
4163	    if (!(m = *mp)) {
4164		/*
4165		 * No matcher, so just match the character
4166		 * itself.
4167		 *
4168		 * TODO: surely this needs quoting if it's a
4169		 * metacharacter?
4170		 */
4171		if (ret) {
4172		    memcpy(p, add, addlen);
4173		    p += addlen;
4174		} else
4175		    len += addlen;
4176	    } else if (m->flags & CMF_RIGHT) {
4177		/*
4178		 * Right-anchored:  match anything followed
4179		 * by the character itself.
4180		 */
4181		if (ret) {
4182		    *p++ = '*';
4183		    /* TODO: quote again? */
4184		    memcpy(p, add, addlen);
4185		    p += addlen;
4186		} else
4187		    len += addlen + 1;
4188	    } else {
4189		/* The usual set of matcher possibilities. */
4190		convchar_t ind;
4191		if (m->line->tp == CPAT_EQUIV &&
4192		    m->word->tp == CPAT_EQUIV) {
4193		    /*
4194		     * Genuine equivalence.  Add the character to match
4195		     * and the equivalent character from the word
4196		     * pattern.
4197		     *
4198		     * TODO: we could be more careful here with special
4199		     * cases as we are in the basic character class
4200		     * code below.
4201		     */
4202		    if (ret) {
4203			*p++ = '[';
4204			memcpy(p, add, addlen);
4205			p += addlen;
4206		    } else
4207			len += addlen + 1;
4208		    if (PATMATCHRANGE(m->line->u.str, addc, &ind, &mt)) {
4209			/*
4210			 * Find the equivalent match for ind in the
4211			 * word pattern.
4212			 */
4213			if ((ind = pattern_match_equivalence
4214			     (m->word, ind, mt, addc)) != CHR_INVALID) {
4215			    if (ret) {
4216				if (imeta(ind)) {
4217				    *p++ = Meta;
4218				    *p++ = ind ^ 32;
4219				} else
4220				    *p++ = ind;
4221			    } else
4222				len += imeta(ind) ? 2 : 1;
4223			}
4224		    }
4225		    if (ret)
4226			*p++ = ']';
4227		    else
4228			len++;
4229		} else {
4230		    int newlen, addadd;
4231
4232		    switch (m->word->tp) {
4233		    case CPAT_NCLASS:
4234			/*
4235			 * TODO: the old logic implies that we need to
4236			 * match *add, i.e. it should be deleted from
4237			 * the set of character's we're not allowed to
4238			 * match.  That's too much like hard work for
4239			 * now.  Indeed, in general it's impossible
4240			 * without trickery.  Consider *add == 'A',
4241			 * range == "[^[:upper:]]": we would have to
4242			 * resort to something like "(A|[^[:upper:]])";
4243			 * and in an expression like that *add may or
4244			 * may not need backslashing.  So we're deep
4245			 * into see-if-we-can-get-away-without
4246			 * territory.
4247			 */
4248			if (ret) {
4249			    *p++ = '[';
4250			    *p++ = '^';
4251			} else
4252			    len += 2;
4253			/*
4254			 * Convert the compiled range string back
4255			 * to an ordinary string.
4256			 */
4257			newlen =
4258			    pattern_range_to_string(m->word->u.str, p);
4259			DPUTS(!newlen, "empty character range");
4260			if (ret) {
4261			    p += newlen;
4262			    *p++ = ']';
4263			} else
4264			    len += newlen + 1;
4265			break;
4266
4267		    case CPAT_CCLASS:
4268			/*
4269			 * If there is an equivalence only on one
4270			 * side it's not equivalent to anything.
4271			 * Treat it as an ordinary character class.
4272			 */
4273		    case CPAT_EQUIV:
4274		    case CPAT_CHAR:
4275			if (ret)
4276			    *p++ = '[';
4277			else
4278			    len++;
4279			/*
4280			 * We needed to add *add specially only if
4281			 * it is not covered by the range.  This
4282			 * is necessary for correct syntax---consider
4283			 * if *add is ] and ] is also the first
4284			 * character in the range.
4285			 */
4286			addadd = !pattern_match1(m->word, addc, &mt);
4287			if (addadd && *add == ']') {
4288			    if (ret)
4289				*p++ = *add;
4290			    else
4291				len++;
4292			}
4293			if (m->word->tp == CPAT_CHAR) {
4294			    /*
4295			     * The matcher just matches a single
4296			     * character, but we need to be able
4297			     * to match *add, too, hence we do
4298			     * this as a [...].
4299			     */
4300			    if (ret) {
4301				if (imeta(m->word->u.chr)) {
4302				    *p++ = Meta;
4303				    *p++ = m->word->u.chr ^ 32;
4304				} else
4305				    *p++ = m->word->u.chr;
4306			    } else
4307				len += imeta(m->word->u.chr) ? 2 : 1;
4308			} else {
4309			    /*
4310			     * Convert the compiled range string back
4311			     * to an ordinary string.
4312			     */
4313			    newlen =
4314				pattern_range_to_string(m->word->u.str, p);
4315			    DPUTS(!newlen, "empty character range");
4316			    if (ret)
4317				p += newlen;
4318			    else
4319				len += newlen;
4320			}
4321			if (addadd && *add != ']') {
4322			    if (ret) {
4323				memcpy(p, add, addlen);
4324				p += addlen;
4325			    } else
4326				len += addlen;
4327			}
4328			if (ret)
4329			    *p++ = ']';
4330			else
4331			    len++;
4332			break;
4333
4334		    case CPAT_ANY:
4335			if (ret)
4336			    *p++ = '?';
4337			else
4338			    len++;
4339			break;
4340		    }
4341		}
4342	    }
4343	    add += addlen;
4344	    mp++;
4345	}
4346	if (ret) {
4347	    *p = '\0';
4348	    return ret;
4349	}
4350	p = ret = zhalloc(len + 1);
4351	add = adds;
4352    }
4353}
4354
4355
4356static char *
4357cfp_matcher_pats(char *matcher, char *add)
4358{
4359    Cmatcher m = parse_cmatcher(NULL, matcher);
4360
4361    if (m && m != pcm_err) {
4362	char *tmp;
4363	int al = strlen(add), zl = ztrlen(add), tl, cl;
4364	VARARR(Cmatcher, ms, zl);
4365	Cmatcher *mp;
4366	Cpattern stopp;
4367	int stopl = 0;
4368
4369	memset(ms, 0, zl * sizeof(Cmatcher));
4370
4371	for (; m && *add; m = m->next) {
4372	    stopp = NULL;
4373	    if (!(m->flags & (CMF_LEFT|CMF_RIGHT))) {
4374		if (m->llen == 1 && m->wlen == 1) {
4375		    for (tmp = add, tl = al, mp = ms; tl; ) {
4376			if (pattern_match(m->line, tmp, NULL, NULL)) {
4377			    if (*mp) {
4378				*tmp = '\0';
4379				al = tmp - add;
4380				break;
4381			    } else
4382				*mp = m;
4383			}
4384			cl = (*tmp == Meta) ? 2 : 1;
4385			tl -= cl;
4386			tmp += cl;
4387			mp += cl;
4388		    }
4389		} else {
4390		    stopp = m->line;
4391		    stopl = m->llen;
4392		}
4393	    } else if (m->flags & CMF_RIGHT) {
4394		if (m->wlen < 0 && !m->llen && m->ralen == 1) {
4395		    for (tmp = add, tl = al, mp = ms; tl; ) {
4396			if (pattern_match(m->right, tmp, NULL, NULL)) {
4397			    if (*mp || (tmp == add && *tmp == '.')) {
4398				*tmp = '\0';
4399				al = tmp - add;
4400				break;
4401			    } else
4402				*mp = m;
4403			}
4404			cl = (*tmp == Meta) ? 2 : 1;
4405			tl -= cl;
4406			tmp += cl;
4407			mp += cl;
4408		    }
4409		} else if (m->llen) {
4410		    stopp = m->line;
4411		    stopl = m->llen;
4412		} else {
4413		    stopp = m->right;
4414		    stopl = m->ralen;
4415		}
4416	    } else {
4417		if (!m->lalen)
4418		    return "";
4419
4420		stopp = m->left;
4421		stopl = m->lalen;
4422	    }
4423	    if (stopp)
4424		for (tmp = add, tl = al; tl >= stopl; ) {
4425		    if (pattern_match(stopp, tmp, NULL, NULL)) {
4426			*tmp = '\0';
4427			al = tmp - add;
4428			break;
4429		    }
4430		    cl = (*tmp == Meta) ? 2 : 1;
4431		    tl -= cl;
4432		    tmp += cl;
4433		}
4434	}
4435	if (*add)
4436	    return cfp_matcher_range(ms, add);
4437    }
4438    return add;
4439}
4440
4441static void
4442cfp_opt_pats(char **pats, char *matcher)
4443{
4444    char *add, **p, *q, *t, *s;
4445
4446    if (!compprefix || !*compprefix)
4447	return;
4448
4449    if (comppatmatch && *comppatmatch) {
4450	tokenize(t = rembslash(dyncat(compprefix, compsuffix)));
4451	remnulargs(t);
4452	if (haswilds(t))
4453	    return;
4454    }
4455    add = (char *) zhalloc(strlen(compprefix) * 2 + 1);
4456    for (s = compprefix, t = add; *s; s++) {
4457	if (*s != '\\' || !s[1] || s[1] == '*' || s[1] == '?' ||
4458	    s[1] == '<' || s[1] == '>' || s[1] == '(' || s[1] == ')' ||
4459	    s[1] == '[' || s[1] == ']' || s[1] == '|' || s[1] == '#' ||
4460	    s[1] == '^' || s[1] == '~' || s[1] == '=') {
4461	    if ((s == compprefix || s[-1] != '\\') &&
4462		(*s == '*' || *s == '?' || *s == '<' || *s == '>' ||
4463		 *s == '(' || *s == ')' || *s == '[' || *s == ']' ||
4464		 *s == '|' || *s == '#' || *s == '^' || *s == '~' ||
4465		 *s == '='))
4466		*t++ = '\\';
4467	    *t++ = *s;
4468	}
4469    }
4470    *t = '\0';
4471    for (p = pats; *add && (q = *p); p++) {
4472	if (*q) {
4473	    q = dupstring(q);
4474	    t = q + strlen(q) - 1;
4475	    if (*t == ')') {
4476		for (s = t--; t > q; t--)
4477		    if (*t == ')' || *t == '|' || *t == '~' || *t == '(')
4478			break;
4479		if (t != q && *t == '(')
4480		    *t = '\0';
4481	    }
4482	    for (; *q && *add; q++) {
4483		if (*q == '\\' && q[1]) {
4484		    for (s = add, q++; *s && *s != *q; s++);
4485		    *s = '\0';
4486		} else if (*q == '<') {
4487		    for (s = add; *s && !idigit(*s); s++);
4488		    *s = '\0';
4489		} else if (*q == '[') {
4490		    int not;
4491		    char *x = ++q;
4492
4493		    if ((not = (*x == '!' || *x == '^')))
4494			x++;
4495		    for (; *x; x++) {
4496			if (x[1] == '-' && x[2]) {
4497			    char c1 = *x, c2 = x[2];
4498
4499			    for (s = add; *s && (*x < c1 || *x > c2); s++);
4500			    *s = '\0';
4501			} else {
4502			    for (s = add; *s && *s != *x; s++);
4503			    *s = '\0';
4504			}
4505		    }
4506		} else if (*q != '?' && *q != '*' && *q != '(' && *q != ')' &&
4507			   *q != '|' && *q != '~' && *q != '#') {
4508		    for (s = add; *s && *s != *q; s++);
4509		    *s = '\0';
4510		}
4511	    }
4512	}
4513    }
4514    if (*add) {
4515	if (*matcher && !(add = cfp_matcher_pats(matcher, add)))
4516	    return;
4517
4518	for (p = pats; *p; p++)
4519	    if (**p == '*')
4520		*p = dyncat(add, *p);
4521    }
4522}
4523
4524static LinkList
4525cfp_bld_pats(UNUSED(int dirs), LinkList names, char *skipped, char **pats)
4526{
4527    LinkList ret = newlinklist();
4528    LinkNode node;
4529    int ol, sl = strlen(skipped), pl, dot;
4530    char **p, *o, *str;
4531
4532    dot = (unset(GLOBDOTS) && compprefix && *compprefix == '.');
4533    for (node = firstnode(names); node; incnode(node)) {
4534	ol = strlen(o = (char *) getdata(node));
4535	for (p = pats; *p; p++) {
4536	    pl = strlen(*p);
4537	    str = (char *) zhalloc(ol + sl + pl + 1);
4538	    strcpy(str, o);
4539	    strcpy(str + ol, skipped);
4540	    strcpy(str + ol + sl, *p);
4541	    addlinknode(ret, str);
4542	    if (dot && **p != '.') {
4543		str = (char *) zhalloc(ol + sl + pl + 2);
4544		strcpy(str, o);
4545		strcpy(str + ol, skipped);
4546		str[ol + sl] = '.';
4547		strcpy(str + ol + sl + 1, *p);
4548		addlinknode(ret, str);
4549	    }
4550	}
4551    }
4552    return ret;
4553}
4554
4555static LinkList
4556cfp_add_sdirs(LinkList final, LinkList orig, char *skipped,
4557	      char *sdirs, char **fake)
4558{
4559    int add = 0;
4560
4561    if (*sdirs && (isset(GLOBDOTS) || (compprefix && *compprefix == '.'))) {
4562	if (!strcmp(sdirs, "yes") || !strcmp(sdirs, "true") ||
4563	    !strcmp(sdirs, "on") || !strcmp(sdirs, "1"))
4564	    add = 2;
4565	else if (!strcmp(sdirs, ".."))
4566	    add = 1;
4567    }
4568    if (add) {
4569	LinkNode node;
4570	char *s1 = dyncat(skipped, "..");
4571	char *s2 = (add == 2 ? dyncat(skipped, ".") : NULL), *m;
4572
4573	for (node = firstnode(orig); node; incnode(node)) {
4574	    if ((m = (char *) getdata(node))) {
4575		addlinknode(final, dyncat(m, s1));
4576		if (s2)
4577		    addlinknode(final, dyncat(m, s2));
4578	    }
4579	}
4580    }
4581    if (fake && *fake) {
4582	LinkNode node;
4583	char *m, *f, *p, *t, *a, c;
4584	int sl = strlen(skipped) + 1;
4585	struct stat st1, st2;
4586	Patprog pprog;
4587
4588	for (; (f = *fake); fake++) {
4589	    f = dupstring(f);
4590	    for (p = t = f; *p; p++) {
4591		if (*p == ':')
4592		    break;
4593		else if (*p == '\\' && p[1] == ':') {
4594		    /*
4595		     * strip quoted colons here; rely
4596		     * on tokenization to strip other backslashes
4597		     */
4598		    p++;
4599		}
4600		*t++ = *p;
4601	    }
4602	    if (*p) {
4603		*t = *p++ = '\0';
4604		if (!*p)
4605		    continue;
4606
4607		tokenize(f);
4608		pprog = patcompile(f, PAT_STATIC, NULL);
4609		untokenize(f);
4610		for (node = firstnode(orig); node; incnode(node)) {
4611		    if ((m = (char *) getdata(node)) &&
4612			((pprog ? pattry(pprog, m) : !strcmp(f, m)) ||
4613			 (!stat(f, &st1) && !stat((*m ? m : "."), &st2) &&
4614			  st1.st_dev == st2.st_dev &&
4615			  st1.st_ino == st2.st_ino))) {
4616			while (*p) {
4617			    while (*p && inblank(*p))
4618				p++;
4619			    if (!*p)
4620				break;
4621			    for (f = t = p; *p; p++) {
4622				if (inblank(*p))
4623				    break;
4624				else if (*p == '\\' && p[1])
4625				    p++;
4626				*t++ = *p;
4627			    }
4628			    c = *t;
4629			    *t = '\0';
4630			    a = (char *) zhalloc(strlen(m) + sl + strlen(f));
4631			    strcpy(a, m);
4632			    strcat(a, skipped);
4633			    strcat(a, f);
4634			    addlinknode(final, a);
4635			    *t = c;
4636			}
4637		    }
4638		}
4639	    }
4640	}
4641    }
4642    return final;
4643}
4644
4645static LinkList
4646cf_pats(int dirs, int noopt, LinkList names, char **accept, char *skipped,
4647	char *matcher, char *sdirs, char **fake, char **pats)
4648{
4649    LinkList ret;
4650    char *dpats[2];
4651
4652    if ((ret = cfp_test_exact(names, accept, skipped)))
4653	return cfp_add_sdirs(ret, names, skipped, sdirs, fake);
4654
4655    if (dirs) {
4656	dpats[0] = "*(-/)";
4657	dpats[1] = NULL;
4658	pats = dpats;
4659    }
4660    if (!noopt)
4661	cfp_opt_pats(pats, matcher);
4662
4663    return cfp_add_sdirs(cfp_bld_pats(dirs, names, skipped, pats),
4664			 names, skipped, sdirs, fake);
4665}
4666
4667/*
4668 * This function looks at device/inode pairs to determine if
4669 * a file is one we should ignore because of its relationship
4670 * to the current or parent directory.
4671 *
4672 * We don't follow symbolic links here, because typically
4673 * a user will not want an explicit link to the current or parent
4674 * directory ignored.
4675 */
4676static void
4677cf_ignore(char **names, LinkList ign, char *style, char *path)
4678{
4679    int pl = strlen(path), tpar, tpwd, found;
4680    struct stat nst, est, st;
4681    char *n, *c, *e;
4682
4683    tpar = !!strstr(style, "parent");
4684    if ((tpwd = !!strstr(style, "pwd")) && lstat(pwd, &est))
4685	tpwd = 0;
4686
4687    if (!tpar && !tpwd)
4688	return;
4689
4690    for (; (n = *names); names++) {
4691	if (!ztat(n, &nst, 1) && S_ISDIR(nst.st_mode)) {
4692	    if (tpwd && nst.st_dev == est.st_dev && nst.st_ino == est.st_ino) {
4693		addlinknode(ign, quotestring(n, NULL, QT_BACKSLASH));
4694		continue;
4695	    }
4696	    if (tpar && !strncmp((c = dupstring(n)), path, pl)) {
4697		found = 0;
4698		while ((e = strrchr(c, '/')) && e > c + pl) {
4699		    *e = '\0';
4700		    if (!ztat(c, &st, 0) &&
4701			st.st_dev == nst.st_dev && st.st_ino == nst.st_ino) {
4702			found = 1;
4703			break;
4704		    }
4705		}
4706		if (found || ((e = strrchr(c, '/')) && e > c + pl &&
4707			      !ztat(c, &st, 1) && st.st_dev == nst.st_dev &&
4708			      st.st_ino == nst.st_ino))
4709		    addlinknode(ign, quotestring(n, NULL, QT_BACKSLASH));
4710	    }
4711	}
4712    }
4713}
4714
4715static LinkList
4716cf_remove_other(char **names, char *pre, int *amb)
4717{
4718    char *p;
4719
4720    if ((p = strchr(pre, '/'))) {
4721	char **n;
4722
4723	*p = '\0';
4724	pre = dyncat(pre, "/");
4725	*p = '/';
4726
4727	for (n = names; *n; n++)
4728	    if (strpfx(pre, *n))
4729		break;
4730
4731	if (*n) {
4732	    LinkList ret = newlinklist();
4733
4734	    for (; *names; names++)
4735		if (strpfx(pre, *names))
4736		    addlinknode(ret, dupstring(*names));
4737
4738	    *amb = 0;
4739
4740	    return ret;
4741	} else {
4742	    if (!(p = *names++))
4743		*amb = 0;
4744	    else {
4745		char *q;
4746
4747		if ((q = strchr((p = dupstring(p)), '/')))
4748		    *q = '\0';
4749
4750                p = dyncat(p, "/");
4751
4752		for (; *names; names++)
4753		    if (!strpfx(p, *names)) {
4754			*amb = 1;
4755			return NULL;
4756		    }
4757	    }
4758	}
4759    } else {
4760	if (!(p = *names++))
4761	    *amb = 0;
4762	else
4763	    for (; *names; names++)
4764		if (strcmp(p, *names)) {
4765		    *amb = 1;
4766		    return NULL;
4767		}
4768    }
4769    return NULL;
4770}
4771
4772static int
4773bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
4774{
4775    if (incompfunc != 1) {
4776	zwarnnam(nam, "can only be called from completion function");
4777	return 1;
4778    }
4779    if (**args != '-') {
4780	zwarnnam(nam, "missing option: %s", *args);
4781	return 1;
4782    }
4783    switch (args[0][1]) {
4784    case 'p':
4785    case 'P':
4786	if (args[0][2] && (args[0][2] != '-' || args[0][3])) {
4787	    zwarnnam(nam, "invalid option: %s", *args);
4788	    return 1;
4789	} else {
4790	    char **tmp;
4791	    LinkList l;
4792
4793	    if (!args[1] || !args[2] || !args[3] || !args[4] || !args[5] ||
4794		!args[6] || (args[0][1] == 'p' && !args[7])) {
4795		zwarnnam(nam, "too few arguments");
4796		return 1;
4797	    }
4798	    queue_signals();
4799	    if (!(tmp = getaparam(args[1]))) {
4800		zwarnnam(nam, "unknown parameter: %s", args[1]);
4801		return 0;
4802	    }
4803	    for (l = newlinklist(); *tmp; tmp++)
4804		addlinknode(l, *tmp);
4805	    set_list_array(args[1], cf_pats((args[0][1] == 'P'), !!args[0][2],
4806					    l, getaparam(args[2]), args[3],
4807					    args[4], args[5],
4808					    getaparam(args[6]), args + 7));
4809	    unqueue_signals();
4810	    return 0;
4811	}
4812    case 'i':
4813	if (args[0][2]) {
4814	    zwarnnam(nam, "invalid option: %s", *args);
4815	    return 1;
4816	} else {
4817	    char **tmp;
4818	    LinkList l;
4819
4820	    if (!args[1] || !args[2] || !args[3] || !args[4]) {
4821		zwarnnam(nam, "too few arguments");
4822		return 1;
4823	    }
4824	    if (args[5]) {
4825		zwarnnam(nam, "too many arguments");
4826		return 1;
4827	    }
4828	    queue_signals();
4829	    tmp = getaparam(args[2]);
4830	    l = newlinklist();
4831	    if (tmp)
4832		for (; *tmp; tmp++)
4833		    addlinknode(l, *tmp);
4834	    if (!(tmp = getaparam(args[1]))) {
4835		unqueue_signals();
4836		zwarnnam(nam, "unknown parameter: %s", args[1]);
4837		return 0;
4838	    }
4839	    cf_ignore(tmp, l, args[3], args[4]);
4840	    unqueue_signals();
4841	    set_list_array(args[2], l);
4842	    return 0;
4843	}
4844    case 'r':
4845	{
4846	    char **tmp;
4847	    LinkList l;
4848	    int ret = 0;
4849
4850	    if (!args[1] || !args[2]) {
4851		zwarnnam(nam, "too few arguments");
4852		return 1;
4853	    }
4854	    if (args[3]) {
4855		zwarnnam(nam, "too many arguments");
4856		return 1;
4857	    }
4858	    queue_signals();
4859	    if (!(tmp = getaparam(args[1]))) {
4860		unqueue_signals();
4861		zwarnnam(nam, "unknown parameter: %s", args[1]);
4862		return 0;
4863	    }
4864	    if ((l = cf_remove_other(tmp, args[2], &ret)))
4865		set_list_array(args[1], l);
4866	    unqueue_signals();
4867	    return ret;
4868	}
4869    }
4870    zwarnnam(nam, "invalid option: %s", *args);
4871    return 1;
4872}
4873
4874static int
4875bin_compgroups(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
4876{
4877    Heap oldheap;
4878    char *n;
4879
4880    if (incompfunc != 1) {
4881	zwarnnam(nam, "can only be called from completion function");
4882	return 1;
4883    }
4884    SWITCHHEAPS(oldheap, compheap) {
4885	while ((n = *args++)) {
4886	    endcmgroup(NULL);
4887	    begcmgroup(n, CGF_NOSORT|CGF_UNIQCON);
4888	    endcmgroup(NULL);
4889	    begcmgroup(n, CGF_UNIQALL);
4890	    endcmgroup(NULL);
4891	    begcmgroup(n, CGF_NOSORT|CGF_UNIQCON);
4892	    endcmgroup(NULL);
4893	    begcmgroup(n, CGF_UNIQALL);
4894	    endcmgroup(NULL);
4895	    begcmgroup(n, CGF_NOSORT);
4896	    endcmgroup(NULL);
4897	    begcmgroup(n, 0);
4898	}
4899    } SWITCHBACKHEAPS(oldheap);
4900
4901    return 0;
4902}
4903
4904static struct builtin bintab[] = {
4905    BUILTIN("comparguments", 0, bin_comparguments, 1, -1, 0, NULL, NULL),
4906    BUILTIN("compdescribe", 0, bin_compdescribe, 3, -1, 0, NULL, NULL),
4907    BUILTIN("compfiles", 0, bin_compfiles, 1, -1, 0, NULL, NULL),
4908    BUILTIN("compgroups", 0, bin_compgroups, 1, -1, 0, NULL, NULL),
4909    BUILTIN("compquote", 0, bin_compquote, 1, -1, 0, "p", NULL),
4910    BUILTIN("comptags", 0, bin_comptags, 1, -1, 0, NULL, NULL),
4911    BUILTIN("comptry", 0, bin_comptry, 0, -1, 0, NULL, NULL),
4912    BUILTIN("compvalues", 0, bin_compvalues, 1, -1, 0, NULL, NULL)
4913};
4914
4915static struct features module_features = {
4916    bintab, sizeof(bintab)/sizeof(*bintab),
4917    NULL, 0,
4918    NULL, 0,
4919    NULL, 0,
4920    0
4921};
4922
4923
4924/**/
4925int
4926setup_(UNUSED(Module m))
4927{
4928    memset(cadef_cache, 0, sizeof(cadef_cache));
4929    memset(cvdef_cache, 0, sizeof(cvdef_cache));
4930
4931    memset(comptags, 0, sizeof(comptags));
4932
4933    lasttaglevel = 0;
4934
4935    return 0;
4936}
4937
4938/**/
4939int
4940features_(Module m, char ***features)
4941{
4942    *features = featuresarray(m, &module_features);
4943    return 0;
4944}
4945
4946/**/
4947int
4948enables_(Module m, int **enables)
4949{
4950    return handlefeatures(m, &module_features, enables);
4951}
4952
4953/**/
4954int
4955boot_(Module m)
4956{
4957    return 0;
4958}
4959
4960/**/
4961int
4962cleanup_(Module m)
4963{
4964    return setfeatureenables(m, &module_features, NULL);
4965}
4966
4967/**/
4968int
4969finish_(UNUSED(Module m))
4970{
4971    int i;
4972
4973    for (i = 0; i < MAX_CACACHE; i++)
4974	freecadef(cadef_cache[i]);
4975    for (i = 0; i < MAX_CVCACHE; i++)
4976	freecvdef(cvdef_cache[i]);
4977
4978    for (i = 0; i < MAX_TAGS; i++)
4979	freectags(comptags[i]);
4980
4981    return 0;
4982}
4983