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