2 * computil.c - completion utilities
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1999 Sven Wischnowsky
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.
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.
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.
30 #include "computil.mdh"
31 #include "computil.pro"
34 /* Help for `_describe'. */
36 typedef struct cdset
*Cdset
;
37 typedef struct cdstr
*Cdstr
;
38 typedef struct cdrun
*Cdrun
;
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 */
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 */
74 int type
; /* see CRT_* below */
75 Cdstr strs
; /* strings in this run */
76 int count
; /* number of strings in this run */
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 */
93 static struct cdstate cd_state
;
94 static int cd_parsed
= 0;
107 for (s
= p
->strs
; s
; s
= sn
) {
109 zfree(s
->sortstr
, strlen(s
->str
) + 1);
112 if (s
->match
!= s
->str
)
114 zfree(s
, sizeof(*s
));
116 for (r
= cd_state
.runs
; r
; r
= rn
) {
118 zfree(r
, sizeof(*r
));
120 zfree(p
, sizeof(*p
));
124 /* Find matches with same descriptions and group them. */
130 Cdstr str1
, str2
, *strp
;
133 cd_state
.groups
= cd_state
.descs
= cd_state
.maxglen
= 0;
136 for (set1
= cd_state
.sets
; set1
; set1
= set1
->next
)
137 for (str1
= set1
->strs
; str1
; str1
= str1
->next
) {
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)
148 width
= str1
->width
+ cd_state
.swidth
;
149 if (width
> cd_state
.maxglen
)
150 cd_state
.maxglen
= width
;
151 strp
= &(str1
->other
);
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
)
160 if (width
> cd_state
.maxglen
)
161 cd_state
.maxglen
= width
;
166 strp
= &(str2
->other
);
178 if (num
> cd_state
.maxg
)
184 /* Calculate longest prefix and suffix and count the strings with
194 cd_state
.pre
= cd_state
.suf
= 0;
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
) {
200 if ((l
= strlen(str
->str
)) > cd_state
.pre
)
202 if ((l
= MB_METASTRWIDTH(str
->str
)) > cd_state
.premaxw
)
203 cd_state
.premaxw
= l
;
206 if ((l
= strlen(str
->desc
)) > cd_state
.suf
)
214 cd_sort(const void *a
, const void *b
)
216 return zstrcmp((*((Cdstr
*) a
))->sortstr
, (*((Cdstr
*) b
))->sortstr
, 0);
226 runp
= &(cd_state
.runs
);
228 if (cd_state
.groups
) {
229 int lines
= cd_state
.groups
+ cd_state
.descs
;
230 VARARR(Cdstr
, grps
, lines
);
231 VARARR(int, wids
, cd_state
.maxg
);
232 Cdstr gs
, gp
, gn
, *gpp
;
237 memset(wids
, 0, cd_state
.maxg
* sizeof(int));
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
;
255 for (; gp
; gp
= gn
) {
258 for (gpp
= &gs
; *gpp
&& (*gpp
)->width
> gp
->width
;
259 gpp
= &((*gpp
)->other
));
263 for (gp
= gs
, i
= 0; gp
; gp
= gp
->other
, i
++)
264 if (gp
->width
> wids
[i
])
271 for (i
= 0; i
< cd_state
.maxg
; i
++) {
272 cd_state
.gprew
+= wids
[i
] + CM_SPACE
;
275 if (cd_state
.gprew
> cd_state
.maxmlen
&& cd_state
.maxglen
> 1)
278 for (i
= 0; i
< lines
; i
++) {
282 s
->sortstr
= ztrdup(s
->str
);
283 unmetafy(s
->sortstr
, &dummy
);
286 qsort(grps
, lines
, sizeof(Cdstr
), cd_sort
);
288 for (i
= lines
, strp
= grps
; i
> 1; i
--, strp
++) {
290 if (!strcmp((*strp
)->desc
, (*strp2
)->desc
))
292 for (j
= i
- 2, strp2
++; j
> 0; j
--, strp2
++)
293 if (!strcmp((*strp
)->desc
, (*strp2
)->desc
)) {
296 memmove(strp
+ 2, strp
+ 1,
297 (strp2
- strp
- 1) * sizeof(Cdstr
));
303 expl
= (Cdrun
) zalloc(sizeof(*run
));
304 expl
->type
= CRT_EXPL
;
305 expl
->strs
= grps
[0];
308 for (i
= lines
, strp
= grps
, strp2
= NULL
; i
; i
--, strp
++) {
315 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
317 run
->type
= CRT_SPEC
;
323 for (i
= cd_state
.maxg
- 1; i
; i
--) {
324 for (d
= 0, j
= lines
, strp
= grps
; j
; j
--, strp
++) {
327 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
329 run
->type
= CRT_DUMMY
;
330 run
->strs
= expl
->strs
;
334 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
336 run
->type
= CRT_SPEC
;
338 run
->strs
->run
= NULL
;
346 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
348 run
->type
= CRT_DUMMY
;
349 run
->strs
= expl
->strs
;
354 runp
= &(expl
->next
);
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
)
368 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
370 run
->type
= CRT_SIMPLE
;
375 } else if (cd_state
.showd
) {
376 for (set
= cd_state
.sets
; set
; set
= set
->next
) {
378 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
380 run
->type
= CRT_DESC
;
382 for (str
= set
->strs
; str
; str
= str
->next
)
388 run
->count
= set
->desc
;
390 if (set
->desc
!= set
->count
) {
391 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
393 run
->type
= CRT_SIMPLE
;
395 for (str
= set
->strs
; str
; str
= str
->next
)
401 run
->count
= set
->count
- set
->desc
;
405 for (set
= cd_state
.sets
; set
; set
= set
->next
)
407 *runp
= run
= (Cdrun
) zalloc(sizeof(*run
));
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
;
421 /* Duplicate and concatenate two arrays. Return the result. */
424 cd_arrcat(char **a
, char **b
)
429 char **r
= (char **) zalloc((arrlen(a
) + arrlen(b
) + 1) *
444 /* Initialisation. Store and calculate the string and matches and so on. */
447 cd_init(char *nam
, char *hide
, char *mlen
, char *sep
,
448 char **opts
, char **args
, int disp
)
456 zsfree(cd_state
.sep
);
457 freecdsets(cd_state
.sets
);
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
= 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")) {
478 *setp
= set
= (Cdset
) zshcalloc(sizeof(*set
));
484 if (!(ap
= get_user_var(*args
))) {
485 zwarnnam(nam
, "invalid argument: %s", *args
);
486 zsfree(cd_state
.sep
);
487 freecdsets(cd_state
.sets
);
490 for (str
= NULL
, strp
= &(set
->strs
); *ap
; ap
++) {
491 *strp
= str
= (Cdstr
) zalloc(sizeof(*str
));
498 for (tmp
= *ap
; *tmp
&& *tmp
!= ':'; tmp
++)
499 if (*tmp
== '\\' && tmp
[1])
503 str
->desc
= ztrdup(rembslash(tmp
+ 1));
507 str
->str
= str
->match
= ztrdup(rembslash(*ap
));
508 str
->len
= strlen(str
->str
);
509 str
->width
= MB_METASTRWIDTH(str
->str
);
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
);
522 for (str
= set
->strs
; str
&& *ap
; str
= str
->next
, ap
++)
523 str
->match
= ztrdup(*ap
);
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);
537 for (ap
= args
; *args
&&
538 (args
[0][0] != '-' || args
[0][1] != '-' || args
[0][2]);
543 set
->opts
= cd_arrcat(ap
, opts
);
552 mg
= cd_state
.maxg
- 1;
564 /* Copy an array with one element in reserve (at the beginning). */
569 char **r
= (char **) zalloc((arrlen(a
) + 2) * sizeof(char *));
579 /* Get the next set. */
582 cd_get(char **params
)
586 if ((run
= cd_state
.runs
)) {
588 char **mats
, **mp
, **dpys
, **dp
, **opts
, *csl
= "";
590 cd_state
.runs
= run
->next
;
594 mats
= mp
= (char **) zalloc((run
->count
+ 1) * sizeof(char *));
595 dpys
= dp
= (char **) zalloc((run
->count
+ 1) * sizeof(char *));
597 for (str
= run
->strs
; str
; str
= str
->run
) {
598 *mp
++ = ztrdup(str
->match
);
599 *dp
++ = ztrdup(str
->str
? str
->str
: str
->match
);
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. */
609 for (mp
= dp
= opts
; *mp
; mp
++) {
610 if (dp
[0][0] == '-' && dp
[0][1] == 'X') {
611 if (!dp
[0][2] && dp
[1])
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) +
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 *));
637 for (str
= run
->strs
; str
; str
= str
->run
) {
638 char *p
= buf
, *pp
, *d
;
641 *mp
++ = ztrdup(str
->match
);
644 memset(p
, ' ', (l
= (cd_state
.premaxw
- str
->width
+ CM_SPACE
)));
646 strcpy(p
, cd_state
.sep
);
650 * copy a character at once until no more screen width
651 * is available. Leave 1 character at the end of screen
654 remw
= columns
- cd_state
.premaxw
- cd_state
.swidth
- 3;
656 w
= MB_METASTRWIDTH(d
);
661 while (remw
> 0 && *d
) {
662 l
= MB_METACHARLEN(d
);
665 w
= MB_METASTRWIDTH(pp
);
680 opts
= cd_arrdup(run
->strs
->set
->opts
);
681 opts
[0] = ztrdup("-l");
686 mats
= (char **) zalloc(2 * sizeof(char *));
687 dpys
= (char **) zalloc(2 * sizeof(char *));
688 mats
[0] = ztrdup(run
->strs
->match
);
689 dpys
[0] = ztrdup(run
->strs
->str
);
690 mats
[1] = dpys
[1] = NULL
;
691 opts
= cd_arrdup(run
->strs
->set
->opts
);
692 for (dp
= opts
+ 1; *dp
; dp
++)
693 if (dp
[0][0] == '-' && dp
[0][1] == 'J')
696 char *s
= tricat("-2V", "", dp
[0] + 2);
701 memmove(opts
, opts
+ 1,
702 (arrlen(opts
+ 1) + 1) * sizeof(char *));
705 opts
[0] = ztrdup("-2V-default-");
713 sprintf(buf
, "-E%d", run
->count
);
715 mats
= (char **) zalloc(sizeof(char *));
716 dpys
= (char **) zalloc(sizeof(char *));
717 mats
[0] = dpys
[0] = NULL
;
719 opts
= cd_arrdup(run
->strs
->set
->opts
);
720 opts
[0] = ztrdup(buf
);
726 default: /* This silences the "might be used uninitialized" warnings */
729 /* add columns as safety margin */
730 VARARR(char, dbuf
, cd_state
.suf
+ cd_state
.slen
+ columns
);
731 char buf
[20], *p
, *pp
, *d
;
732 int i
= run
->count
, remw
, w
, l
;
734 sprintf(buf
, "-E%d", i
);
736 mats
= (char **) zalloc(sizeof(char *));
737 dpys
= (char **) zalloc((i
+ 1) * sizeof(char *));
739 for (dp
= dpys
, str
= run
->strs
; str
; str
= str
->run
) {
740 if (str
->run
&& !strcmp(str
->desc
, str
->run
->desc
)) {
745 strcpy(dbuf
, cd_state
.sep
);
746 remw
= columns
- cd_state
.gprew
- cd_state
.swidth
- CM_SPACE
;
747 p
= pp
= dbuf
+ cd_state
.slen
;
749 w
= MB_METASTRWIDTH(d
);
755 while (remw
> 0 && *d
) {
756 l
= MB_METACHARLEN(d
);
759 w
= MB_METASTRWIDTH(pp
);
774 *dp
++ = ztrdup(dbuf
);
776 mats
[0] = *dp
= NULL
;
778 opts
= cd_arrdup(run
->strs
->set
->opts
);
779 opts
[0] = ztrdup(buf
);
785 setsparam(params
[0], ztrdup(csl
));
786 setaparam(params
[1], opts
);
787 setaparam(params
[2], mats
);
788 setaparam(params
[3], dpys
);
790 zfree(run
, sizeof(*run
));
799 bin_compdescribe(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
801 int n
= arrlen(args
);
803 if (incompfunc
!= 1) {
804 zwarnnam(nam
, "can only be called from completion function");
807 if (!args
[0][0] || !args
[0][1] || args
[0][2]) {
808 zwarnnam(nam
, "invalid argument: %s", args
[0]);
811 switch (args
[0][1]) {
814 zwarnnam(nam
, "not enough arguments");
818 return cd_init(nam
, args
[1], args
[2], "", NULL
, args
+ 3, 0);
821 zwarnnam(nam
, "not enough arguments");
827 if (!(opts
= getaparam(args
[4]))) {
828 zwarnnam(nam
, "unknown parameter: %s", args
[4]);
831 return cd_init(nam
, args
[1], args
[2], args
[3], opts
, args
+ 5, 1);
836 zwarnnam(nam
, (n
< 5 ? "not enough arguments" :
837 "too many arguments"));
840 return cd_get(args
+ 1);
842 zwarnnam(nam
, "no parsed state");
846 zwarnnam(nam
, "invalid option: %s", args
[0]);
850 /* Help for `_arguments'. */
852 typedef struct cadef
*Cadef
;
853 typedef struct caopt
*Caopt
;
854 typedef struct caarg
*Caarg
;
856 /* Cache for a set of _arguments-definitions. */
859 Cadef next
; /* next in cache */
860 Cadef snext
; /* next set */
861 Caopt opts
; /* the options */
862 int nopts
, ndopts
, nodopts
; /* number of options/direct/optional direct */
863 Caarg args
; /* the normal arguments */
864 Caarg rest
; /* the rest-argument */
865 char **defs
; /* the original strings */
866 int ndefs
; /* number of ... */
867 int lastt
; /* last time this was used */
868 Caopt
*single
; /* array of single-letter options */
869 char *match
; /* -M spec to use */
870 int argsactive
; /* if arguments are still allowed */
871 /* used while parsing a command line */
872 char *set
; /* set name prefix (<name>-), shared */
873 char *sname
; /* set name */
874 int flags
; /* see CDF_* below */
875 char *nonarg
; /* pattern for non-args (-A argument) */
880 /* Description for an option. */
884 char *name
; /* option name */
885 char *descr
; /* the description */
886 char **xor; /* if this, then not ... */
887 int type
; /* type, CAO_* */
888 Caarg args
; /* option arguments */
889 int active
; /* still allowed on command line */
890 int num
; /* it's the num'th option */
891 char *set
; /* set name, shared */
892 int not; /* don't complete this option (`!...') */
897 #define CAO_ODIRECT 3
901 /* Description for an argument */
905 char *descr
; /* description */
906 char **xor; /* if this, then not ... */
907 char *action
; /* what to do for it */
908 int type
; /* CAA_* below */
909 char *end
; /* end-pattern for ::<pat>:... */
910 char *opt
; /* option name if for an option */
911 int num
; /* it's the num'th argument */
912 int min
; /* it's also this argument, using opt. args */
913 int direct
; /* number was given directly */
914 int active
; /* still allowed on command line */
915 char *set
; /* set name, shared */
924 /* The cache of parsed descriptons. */
926 #define MAX_CACACHE 8
927 static Cadef cadef_cache
[MAX_CACACHE
];
929 /* Compare two arrays of strings for equality. */
932 arrcmp(char **a
, char **b
)
940 if (strcmp(*a
++, *b
++))
947 /* Memory stuff. Obviously. */
962 zfree(a
, sizeof(*a
));
980 for (p
= d
->opts
; p
; p
= n
) {
987 zfree(p
, sizeof(*p
));
993 zfree(d
->single
, 256 * sizeof(Caopt
));
994 zfree(d
, sizeof(*d
));
999 /* Remove backslashes before colons. */
1002 rembslashcolon(char *s
)
1006 r
= p
= s
= dupstring(s
);
1009 if (s
[0] != '\\' || s
[1] != ':')
1018 /* Add backslashes before colons. */
1021 bslashcolon(char *s
)
1025 r
= p
= zhalloc((2 * strlen(s
)) + 1);
1037 /* Parse an argument definition. */
1040 parse_caarg(int mult
, int type
, int num
, int opt
, char *oname
, char **def
,
1043 Caarg ret
= (Caarg
) zalloc(sizeof(*ret
));
1044 char *p
= *def
, *d
, sav
;
1047 ret
->descr
= ret
->action
= ret
->end
= NULL
;
1050 ret
->min
= num
- opt
;
1052 ret
->opt
= ztrdup(oname
);
1056 /* Get the description. */
1058 for (d
= p
; *p
&& *p
!= ':'; p
++)
1059 if (*p
== '\\' && p
[1])
1063 ret
->descr
= ztrdup(rembslashcolon(d
));
1065 /* Get the action if there is one. */
1069 for (d
= ++p
; *p
&& *p
!= ':'; p
++)
1070 if (*p
== '\\' && p
[1])
1074 ret
->action
= ztrdup(rembslashcolon(d
));
1078 ret
->action
= ztrdup(rembslashcolon(p
+ 1));
1080 ret
->action
= ztrdup("");
1087 alloc_cadef(char **args
, int single
, char *match
, char *nonarg
, int flags
)
1091 ret
= (Cadef
) zalloc(sizeof(*ret
));
1092 ret
->next
= ret
->snext
= NULL
;
1094 ret
->args
= ret
->rest
= NULL
;
1095 ret
->nonarg
= ztrdup(nonarg
);
1097 ret
->defs
= zarrdup(args
);
1098 ret
->ndefs
= arrlen(args
);
1103 ret
->lastt
= time(0);
1104 ret
->set
= ret
->sname
= NULL
;
1106 ret
->single
= (Caopt
*) zalloc(256 * sizeof(Caopt
));
1107 memset(ret
->single
, 0, 256 * sizeof(Caopt
));
1110 ret
->match
= ztrdup(match
);
1117 set_cadef_opts(Cadef def
)
1122 for (argp
= def
->args
, xnum
= 0; argp
; argp
= argp
->next
) {
1124 argp
->min
= argp
->num
- xnum
;
1125 if (argp
->type
== CAA_OPT
)
1130 /* Parse an array of definitions. */
1133 parse_cadef(char *nam
, char **args
)
1137 char **orig_args
= args
, *p
, *q
, *match
= "r:|[_-]=* r:|=*", **xor, **sargs
;
1138 char *adpre
, *adsuf
, *axor
= NULL
, *doset
= NULL
, **setp
= NULL
;
1139 char *nonarg
= NULL
;
1140 int single
= 0, anum
= 1, xnum
, nopts
, ndopts
, nodopts
, flags
= 0;
1141 int state
= 0, not = 0;
1143 nopts
= ndopts
= nodopts
= 0;
1145 /* First string is the auto-description definition. */
1147 for (p
= args
[0]; *p
&& (p
[0] != '%' || p
[1] != 'd'); p
++);
1151 adpre
= dupstring(args
[0]);
1153 adsuf
= dupstring(p
+ 2);
1155 adpre
= adsuf
= NULL
;
1157 /* Now get the -s, -A, -S and -M options. */
1160 while ((p
= *args
) && *p
== '-' && p
[1]) {
1161 for (q
= ++p
; *q
; q
++)
1162 if (*q
== 'M' || *q
== 'A') {
1165 } else if (*q
!= 's' && *q
!= 'S')
1176 else if (*p
== 'A') {
1184 } else if (*p
== 'M') {
1199 if (*args
&& !strcmp(*args
, ":"))
1205 tokenize(nonarg
= dupstring(nonarg
));
1207 /* Looks good. Optimistically allocate the cadef structure. */
1209 all
= ret
= alloc_cadef(orig_args
, single
, match
, nonarg
, flags
);
1210 optp
= &(ret
->opts
);
1215 /* Get the definitions. */
1217 for (; *args
; args
++) {
1218 if (args
[0][0] == '-' && !args
[0][1] && args
[1]) {
1227 if (*p
== '(' && p
[l
] == ')') {
1228 axor
= p
= dupstring(p
+ 1);
1232 ret
->set
= doset
= tricat(p
, "-", "");
1233 ret
->sname
= ztrdup(p
);
1241 ret
->ndopts
= ndopts
;
1242 ret
->nodopts
= nodopts
;
1243 set_cadef_opts(ret
);
1244 ret
= ret
->snext
= alloc_cadef(NULL
, single
, NULL
, nonarg
, flags
);
1245 optp
= &(ret
->opts
);
1246 nopts
= ndopts
= nodopts
= 0;
1251 p
= dupstring(*args
);
1253 if ((not = (*p
== '!')))
1256 /* There is a xor list, get it. */
1258 LinkList list
= newlinklist();
1262 while (*p
&& *p
!= ')') {
1263 for (p
++; inblank(*p
); p
++);
1267 for (q
= p
++; *p
&& *p
!= ')' && !inblank(*p
); p
++);
1274 addlinknode(list
, dupstring(q
));
1278 /* Oops, end-of-string. */
1281 zwarnnam(nam
, "invalid argument: %s", *args
);
1286 xor = (char **) zalloc((xnum
+ 2) * sizeof(char *));
1287 for (node
= firstnode(list
), xp
= xor; node
; incnode(node
), xp
++)
1288 *xp
= ztrdup((char *) getdata(node
));
1290 *xp
++ = ztrdup(axor
);
1291 xp
[0] = xp
[1] = NULL
;
1294 } else if (doset
&& axor
) {
1296 xor = (char **) zalloc(3 * sizeof(char *));
1297 xor[0] = ztrdup(axor
);
1298 xor[1] = xor[2] = NULL
;
1302 if (*p
== '-' || *p
== '+' ||
1303 (*p
== '*' && (p
[1] == '-' || p
[1] == '+'))) {
1304 /* It's an option. */
1307 int multi
, otype
= CAO_NEXT
, again
= 0;
1308 char *name
, *descr
, c
, *againp
= NULL
;
1312 /* Allowed more than once? */
1313 if ((multi
= (*p
== '*')))
1316 if (((p
[0] == '-' && p
[1] == '+') ||
1317 (p
[0] == '+' && p
[1] == '-')) &&
1318 p
[2] && p
[2] != ':' && p
[2] != '[' &&
1319 p
[2] != '=' && p
[2] != '-' && p
[2] != '+') {
1320 /* It's a -+ or +- definition. We just execute the whole
1321 * stuff twice for such things. */
1322 againp
= dupstring(p
);
1324 *p
= (again
? '-' : '+');
1328 /* If it's a long option skip over the first `-'. */
1329 if (p
[0] == '-' && p
[1] == '-')
1334 zwarnnam(nam
, "invalid argument: %s", *args
);
1338 /* Skip over the name. */
1339 for (p
++; *p
&& *p
!= ':' && *p
!= '[' &&
1340 ((*p
!= '-' && *p
!= '+') ||
1341 (p
[1] != ':' && p
[1] != '[')) &&
1343 (p
[1] != ':' && p
[1] != '[' && p
[1] != '-')); p
++)
1344 if (*p
== '\\' && p
[1])
1347 /* The character after the option name specifies the type. */
1353 } else if (c
== '+') {
1354 otype
= CAO_ODIRECT
;
1356 } else if (c
== '=') {
1358 if ((c
= *++p
) == '-') {
1363 /* Get the optional description, if any. */
1365 for (descr
= ++p
; *p
&& *p
!= ']'; p
++)
1366 if (*p
== '\\' && p
[1])
1371 zwarnnam(nam
, "invalid option definition: %s", *args
);
1379 if (c
&& c
!= ':') {
1381 zwarnnam(nam
, "invalid option definition: %s", *args
);
1384 /* Add the option name to the xor list if not `*-...'. */
1387 xor = (char **) zalloc(2 * sizeof(char *));
1388 xor[0] = xor[1] = NULL
;
1391 xor[xnum
] = ztrdup(rembslashcolon(name
));
1394 /* There's at least one argument. */
1396 Caarg
*oargp
= &oargs
;
1397 int atype
, rest
, oanum
= 1, onum
= 0;
1400 /* Loop over the arguments. */
1406 /* Get the argument type. */
1410 } else if (*p
== '*') {
1414 for (end
= p
++; *p
&& *p
!= ':'; p
++)
1415 if (*p
== '\\' && p
[1])
1419 end
= dupstring(end
);
1426 zwarnnam(nam
, "invalid option definition: %s",
1442 /* And the definition. */
1444 *oargp
= parse_caarg(!rest
, atype
, oanum
++, onum
,
1446 if (atype
== CAA_OPT
)
1449 (*oargp
)->end
= ztrdup(end
);
1450 oargp
= &((*oargp
)->next
);
1456 /* Store the option definition. */
1458 *optp
= opt
= (Caopt
) zalloc(sizeof(*opt
));
1459 optp
= &((*optp
)->next
);
1463 opt
->name
= ztrdup(rembslashcolon(name
));
1465 opt
->descr
= ztrdup(descr
);
1466 else if (adpre
&& oargs
&& !oargs
->next
) {
1469 for (d
= oargs
->descr
; *d
; d
++)
1474 opt
->descr
= tricat(adpre
, oargs
->descr
, adsuf
);
1479 opt
->xor = (again
== 1 && xor ? zarrdup(xor) : xor);
1485 if (otype
== CAO_DIRECT
|| otype
== CAO_EQUAL
)
1487 else if (otype
== CAO_ODIRECT
|| otype
== CAO_OEQUAL
)
1490 /* If this is for single-letter option we also store a
1491 * pointer for the definition in the array for fast lookup. */
1493 if (single
&& name
[1] && !name
[2])
1494 ret
->single
[STOUC(name
[1])] = opt
;
1497 /* Do it all again for `*-...'. */
1501 } else if (*p
== '*') {
1502 /* It's a rest-argument definition. */
1504 int type
= CAA_REST
;
1511 zwarnnam(nam
, "invalid rest argument definition: %s", *args
);
1516 zwarnnam(nam
, "doubled rest argument definition: %s", *args
);
1526 ret
->rest
= parse_caarg(0, type
, -1, 0, NULL
, &p
, doset
);
1527 ret
->rest
->xor = xor;
1529 /* It's a normal argument definition. */
1531 int type
= CAA_NORMAL
, direct
;
1532 Caarg arg
, tmp
, pre
;
1537 if ((direct
= idigit(*p
))) {
1538 /* Argment number is given. */
1541 while (*p
&& idigit(*p
))
1542 num
= (num
* 10) + (((int) *p
++) - '0');
1546 /* Default number. */
1551 zwarnnam(nam
, "invalid argument: %s", *args
);
1557 /* Optional argument. */
1561 arg
= parse_caarg(0, type
, anum
- 1, 0, NULL
, &p
, doset
);
1563 arg
->direct
= direct
;
1565 /* Sort the new definition into the existing list. */
1567 for (tmp
= ret
->args
, pre
= NULL
;
1568 tmp
&& tmp
->num
< anum
- 1;
1569 pre
= tmp
, tmp
= tmp
->next
);
1571 if (tmp
&& tmp
->num
== anum
- 1) {
1574 zwarnnam(nam
, "doubled argument definition: %s", *args
);
1585 ret
->ndopts
= ndopts
;
1586 ret
->nodopts
= nodopts
;
1587 set_cadef_opts(ret
);
1592 /* Given an array of definitions, return the cadef for it. From the cache
1593 * are newly built. */
1596 get_cadef(char *nam
, char **args
)
1598 Cadef
*p
, *min
, new;
1599 int i
, na
= arrlen(args
);
1601 for (i
= MAX_CACACHE
, p
= cadef_cache
, min
= NULL
; i
&& *p
; p
++, i
--)
1602 if (*p
&& na
== (*p
)->ndefs
&& arrcmp(args
, (*p
)->defs
)) {
1603 (*p
)->lastt
= time(0);
1606 } else if (!min
|| !*p
|| (*p
)->lastt
< (*min
)->lastt
)
1610 if ((new = parse_cadef(nam
, args
))) {
1618 * Get the option used in a word from the line, if any.
1620 * "d" is a complete set of argument/option definitions to scan.
1621 * "line" is the word we are scanning.
1622 * "full" indicates that the option must match a full word; otherwise
1623 * we look for "=" arguments or prefixes.
1624 * *"end" is set to point to the end of the option, in some cases
1625 * leaving an option argument after it.
1629 ca_get_opt(Cadef d
, char *line
, int full
, char **end
)
1633 /* The full string may be an option. */
1635 for (p
= d
->opts
; p
; p
= p
->next
)
1636 if (p
->active
&& !strcmp(p
->name
, line
)) {
1638 *end
= line
+ strlen(line
);
1644 /* The string from the line probably only begins with an option. */
1645 for (p
= d
->opts
; p
; p
= p
->next
)
1646 if (p
->active
&& ((!p
->args
|| p
->type
== CAO_NEXT
) ?
1647 !strcmp(p
->name
, line
) : strpfx(p
->name
, line
))) {
1649 /* Return a pointer to the end of the option. */
1650 int l
= strlen(p
->name
);
1652 if ((p
->type
== CAO_OEQUAL
|| p
->type
== CAO_EQUAL
) &&
1664 /* Same as above, only for single-letter-style. */
1667 ca_get_sopt(Cadef d
, char *line
, char **end
, LinkList
*lp
)
1674 for (p
= NULL
; *line
; line
++) {
1675 if ((p
= d
->single
[STOUC(*line
)]) && p
->active
&&
1676 p
->args
&& p
->name
[0] == pre
) {
1677 if (p
->type
== CAO_NEXT
) {
1679 *lp
= l
= newlinklist();
1684 if ((p
->type
== CAO_OEQUAL
|| p
->type
== CAO_EQUAL
) &&
1692 } else if (!p
|| (p
&& !p
->active
))
1694 pp
= (p
->name
[0] == pre
? p
: NULL
);
1702 /* Return the n'th argument definition. */
1705 ca_get_arg(Cadef d
, int n
)
1707 if (d
->argsactive
) {
1710 while (a
&& (!a
->active
|| n
< a
->min
|| n
> a
->num
)) {
1715 if (a
&& a
->min
<= n
&& a
->num
>= n
&& a
->active
)
1718 return (d
->rest
&& d
->rest
->active
? d
->rest
: NULL
);
1723 /* Use a xor list, marking options as inactive. */
1725 static LinkList ca_xor
;
1728 ca_inactive(Cadef d
, char **xor, int cur
, int opts
, char *optname
)
1730 if ((xor || opts
) && cur
<= compcurrent
) {
1733 int sl
= (d
->set
? (int)strlen(d
->set
) : -1), set
= 0;
1735 for (; (x
= (opts
? "-" : *xor)); xor++) {
1736 if (optname
&& optname
[0] == x
[0] && strcmp(optname
, x
))
1739 addlinknode(ca_xor
, x
);
1742 if (strpfx(d
->set
, x
)) {
1745 } else if (!strncmp(d
->set
, x
, sl
- 1)) {
1748 for (p
= d
->opts
; p
; p
= p
->next
)
1756 if (x
[0] == ':' && !x
[1]) {
1760 for (a
= d
->args
; a
; a
= a
->next
)
1763 if (d
->rest
&& (!set
|| d
->rest
->set
))
1764 d
->rest
->active
= 0;
1767 } else if (x
[0] == '-' && !x
[1]) {
1770 for (p
= d
->opts
; p
; p
= p
->next
)
1773 } else if (x
[0] == '*' && !x
[1]) {
1774 if (d
->rest
&& (!set
|| d
->rest
->set
))
1775 d
->rest
->active
= 0;
1776 } else if (idigit(x
[0])) {
1780 while (a
&& a
->num
< n
)
1783 if (a
&& a
->num
== n
&& (!set
|| a
->set
))
1785 } else if ((opt
= ca_get_opt(d
, x
, 1, NULL
)) && (!set
|| opt
->set
))
1795 /* State when parsing a command line. */
1797 typedef struct castate
*Castate
;
1800 * **** DOCUMENT ME ****
1802 * This structure and its use are a nightmare.
1811 int opt
, arg
, argbeg
, optbeg
, nargbeg
, restbeg
, curpos
, argend
;
1812 int inopt
, inrest
, inarg
, nth
, doff
, singles
, oopt
, actopts
;
1817 static struct castate ca_laststate
;
1818 static int ca_parsed
= 0, ca_alloced
= 0;
1821 freecastate(Castate s
)
1826 freelinklist(s
->args
, freestr
);
1827 for (i
= s
->nopts
, p
= s
->oargs
; i
--; p
++)
1829 freelinklist(*p
, freestr
);
1830 zfree(s
->oargs
, s
->d
->nopts
* sizeof(LinkList
));
1833 /* Return a copy of an option's argument, ignoring possible quoting
1834 * in the option name. */
1837 ca_opt_arg(Caopt opt
, char *line
)
1839 char *o
= opt
->name
;
1844 if (*line
== '\\' || *line
== '\'' || *line
== '"')
1846 if (!*o
|| *o
!= *line
)
1851 if (*line
&& (opt
->type
== CAO_EQUAL
|| opt
->type
== CAO_OEQUAL
)) {
1857 return ztrdup(line
);
1860 /* Parse a command line. */
1863 ca_parse_line(Cadef d
, int multi
, int first
)
1866 Caopt ptr
, wasopt
= NULL
, dopt
;
1867 struct castate state
;
1868 char *line
, *oline
, *pe
, **argxor
= NULL
;
1869 int cur
, doff
, argend
, arglast
, ne
;
1870 Patprog endpat
= NULL
, napat
= NULL
;
1871 LinkList sopts
= NULL
;
1873 /* Free old state. */
1875 if (first
&& ca_alloced
) {
1876 Castate s
= &ca_laststate
, ss
;
1884 /* Mark everything as active. */
1886 for (ptr
= d
->opts
; ptr
; ptr
= ptr
->next
)
1890 d
->rest
->active
= 1;
1891 for (adef
= d
->args
; adef
; adef
= adef
->next
)
1894 /* Default values for the state. */
1898 state
.nopts
= d
->nopts
;
1899 state
.def
= state
.ddef
= NULL
;
1900 state
.curopt
= state
.dopt
= NULL
;
1901 state
.argbeg
= state
.optbeg
= state
.nargbeg
= state
.restbeg
= state
.actopts
=
1902 state
.nth
= state
.inopt
= state
.inarg
= state
.opt
= state
.arg
= 1;
1903 state
.argend
= argend
= arrlen(compwords
) - 1;
1904 state
.inrest
= state
.doff
= state
.singles
= state
.doff
= state
.oopt
= 0;
1905 state
.curpos
= compcurrent
;
1906 state
.args
= znewlinklist();
1907 state
.oargs
= (LinkList
*) zalloc(d
->nopts
* sizeof(LinkList
));
1908 memset(state
.oargs
, 0, d
->nopts
* sizeof(LinkList
));
1912 memcpy(&ca_laststate
, &state
, sizeof(state
));
1914 if (!compwords
[1]) {
1915 ca_laststate
.opt
= ca_laststate
.arg
= 0;
1920 napat
= patcompile(d
->nonarg
, 0, NULL
);
1922 /* Loop over the words from the line. */
1924 for (line
= compwords
[1], cur
= 2, state
.curopt
= NULL
, state
.def
= NULL
;
1925 line
; line
= compwords
[cur
++]) {
1928 doff
= state
.singles
= arglast
= 0;
1932 line
= dupstring(line
);
1935 parse_subst_string(line
);
1940 if (ca_inactive(d
, argxor
, cur
, 0, NULL
) ||
1941 ((d
->flags
& CDF_SEP
) && cur
!= compcurrent
&& !strcmp(line
, "--"))) {
1942 if (ca_inactive(d
, NULL
, cur
, 1, NULL
))
1946 /* We've got a definition for an argument, skip to the next. */
1951 zaddlinknode(state
.oargs
[state
.curopt
->num
], ztrdup(oline
));
1953 if ((state
.opt
= (state
.def
->type
== CAA_OPT
)) && state
.def
->opt
)
1956 if (state
.def
->type
== CAA_REST
|| state
.def
->type
== CAA_RARGS
||
1957 state
.def
->type
== CAA_RREST
) {
1958 if (state
.def
->end
&& pattry(endpat
, line
)) {
1960 state
.curopt
= NULL
;
1961 state
.opt
= state
.arg
= 1;
1962 state
.argend
= ca_laststate
.argend
= cur
- 1;
1965 } else if ((state
.def
= state
.def
->next
)) {
1967 state
.argend
= argend
;
1968 } else if (sopts
&& nonempty(sopts
)) {
1969 state
.curopt
= (Caopt
) uremnode(sopts
, firstnode(sopts
));
1970 state
.def
= state
.curopt
->args
;
1972 state
.argbeg
= state
.optbeg
= state
.inopt
= cur
;
1973 state
.argend
= argend
;
1974 doff
= state
.doff
= 0;
1976 if (!state
.oargs
[state
.curopt
->num
])
1977 state
.oargs
[state
.curopt
->num
] = znewlinklist();
1980 state
.curopt
= NULL
;
1984 state
.opt
= state
.arg
= 1;
1985 state
.curopt
= NULL
;
1988 state
.opt
= (line
[0] ? (line
[1] ? 2 : 1) : 0);
1994 /* See if it's an option. */
1996 if (state
.opt
== 2 && (state
.curopt
= ca_get_opt(d
, line
, 0, &pe
)) &&
1997 (state
.curopt
->type
== CAO_OEQUAL
?
1998 (compwords
[cur
] || pe
[-1] == '=') :
1999 (state
.curopt
->type
== CAO_EQUAL
?
2000 (pe
[-1] == '=' || !pe
[0]) : 1))) {
2002 if ((ddef
= state
.def
= ((state
.curopt
->type
!= CAO_EQUAL
||
2004 state
.curopt
->args
: NULL
)))
2005 dopt
= state
.curopt
;
2008 state
.optbeg
= state
.argbeg
= state
.inopt
= cur
;
2009 state
.argend
= argend
;
2010 state
.singles
= (d
->single
&& (!pe
|| !*pe
) &&
2011 state
.curopt
->name
[1] && !state
.curopt
->name
[2]);
2013 if (!state
.oargs
[state
.curopt
->num
])
2014 state
.oargs
[state
.curopt
->num
] = znewlinklist();
2016 if (ca_inactive(d
, state
.curopt
->xor, cur
, 0,
2017 (cur
== compcurrent
? state
.curopt
->name
: NULL
)))
2020 /* Collect the argument strings. Maybe. */
2023 (state
.curopt
->type
== CAO_DIRECT
||
2024 state
.curopt
->type
== CAO_EQUAL
||
2025 (state
.curopt
->type
== CAO_ODIRECT
&& pe
[0]) ||
2026 (state
.curopt
->type
== CAO_OEQUAL
&&
2027 (pe
[0] || pe
[-1] == '=')))) {
2028 if (state
.def
->type
!= CAA_REST
&&
2029 state
.def
->type
!= CAA_RARGS
&&
2030 state
.def
->type
!= CAA_RREST
)
2031 state
.def
= state
.def
->next
;
2033 zaddlinknode(state
.oargs
[state
.curopt
->num
],
2034 ca_opt_arg(state
.curopt
, oline
));
2039 if (!d
->single
|| (state
.curopt
->name
[1] && state
.curopt
->name
[2]))
2040 wasopt
= state
.curopt
;
2041 state
.curopt
= NULL
;
2043 } else if (state
.opt
== 2 && d
->single
&&
2044 ((state
.curopt
= ca_get_sopt(d
, line
, &pe
, &sopts
)) ||
2045 (cur
!= compcurrent
&& sopts
&& nonempty(sopts
)))) {
2046 /* Or maybe it's a single-letter option? */
2051 if (cur
!= compcurrent
&& sopts
&& nonempty(sopts
))
2052 state
.curopt
= (Caopt
) uremnode(sopts
, firstnode(sopts
));
2054 if (!state
.oargs
[state
.curopt
->num
])
2055 state
.oargs
[state
.curopt
->num
] = znewlinklist();
2057 state
.def
= state
.curopt
->args
;
2058 ddef
= (state
.curopt
->type
== CAO_NEXT
&& cur
== compcurrent
?
2060 dopt
= state
.curopt
;
2062 state
.optbeg
= state
.argbeg
= state
.inopt
= cur
;
2063 state
.argend
= argend
;
2064 state
.singles
= (!pe
|| !*pe
);
2066 for (p
= line
+ 1; p
< pe
; p
++) {
2067 if ((tmpopt
= d
->single
[STOUC(*p
)])) {
2068 if (!state
.oargs
[tmpopt
->num
])
2069 state
.oargs
[tmpopt
->num
] = znewlinklist();
2071 if (ca_inactive(d
, tmpopt
->xor, cur
, 0,
2072 (cur
== compcurrent
? tmpopt
->name
: NULL
)))
2077 (state
.curopt
->type
== CAO_DIRECT
||
2078 state
.curopt
->type
== CAO_EQUAL
||
2079 (state
.curopt
->type
== CAO_ODIRECT
&& pe
[0]) ||
2080 (state
.curopt
->type
== CAO_OEQUAL
&&
2081 (pe
[0] || pe
[-1] == '=')))) {
2082 if (state
.def
->type
!= CAA_REST
&&
2083 state
.def
->type
!= CAA_RARGS
&&
2084 state
.def
->type
!= CAA_RREST
)
2085 state
.def
= state
.def
->next
;
2087 zaddlinknode(state
.oargs
[state
.curopt
->num
],
2088 ca_opt_arg(state
.curopt
, line
));
2093 state
.curopt
= NULL
;
2094 } else if (multi
&& (*line
== '-' || *line
== '+') && cur
!= compcurrent
2096 /**** Ouch. Using this will disable the mutual exclusion
2097 of different sets. Not using it will make the -A
2098 pattern be effectively ignored with multiple sets. */
2099 && (!napat
|| !pattry(napat
, line
))
2103 else if (state
.arg
&& (!napat
|| !pattry(napat
, line
))) {
2104 /* Otherwise it's a normal argument. */
2105 if (napat
&& ca_inactive(d
, NULL
, cur
+ 1, 1, NULL
))
2111 state
.nargbeg
= cur
- 1;
2112 state
.argend
= argend
;
2114 if (!d
->args
&& !d
->rest
&& *line
&& *line
!= '-' && *line
!= '+') {
2115 if (!multi
&& cur
> compcurrent
)
2119 if ((adef
= state
.def
= ca_get_arg(d
, state
.nth
)) &&
2120 (state
.def
->type
== CAA_RREST
||
2121 state
.def
->type
== CAA_RARGS
)) {
2123 state
.opt
= (cur
== state
.nargbeg
+ 1 &&
2124 (!multi
|| !*line
||
2125 *line
== '-' || *line
== '+'));
2126 state
.optbeg
= state
.nargbeg
;
2127 state
.argbeg
= cur
- 1;
2128 state
.argend
= argend
;
2130 for (; line
; line
= compwords
[cur
++])
2131 zaddlinknode(state
.args
, ztrdup(line
));
2133 memcpy(&ca_laststate
, &state
, sizeof(state
));
2134 ca_laststate
.ddef
= NULL
;
2135 ca_laststate
.dopt
= NULL
;
2136 ca_laststate
.doff
= 0;
2139 zaddlinknode(state
.args
, ztrdup(line
));
2141 state
.oopt
= adef
->num
- state
.nth
;
2144 argxor
= state
.def
->xor;
2146 if (state
.def
&& state
.def
->type
!= CAA_NORMAL
&&
2147 state
.def
->type
!= CAA_OPT
&& state
.inarg
) {
2148 state
.restbeg
= cur
;
2150 } else if (!state
.def
|| state
.def
->type
== CAA_NORMAL
||
2151 state
.def
->type
== CAA_OPT
)
2156 /* Do the end-pattern test if needed. */
2158 if (state
.def
&& state
.curopt
&&
2159 (state
.def
->type
== CAA_RREST
|| state
.def
->type
== CAA_RARGS
)) {
2161 endpat
= patcompile(state
.def
->end
, 0, NULL
);
2163 LinkList l
= state
.oargs
[state
.curopt
->num
];
2165 if (cur
< compcurrent
)
2166 memcpy(&ca_laststate
, &state
, sizeof(state
));
2168 for (; line
; line
= compwords
[cur
++])
2169 zaddlinknode(l
, ztrdup(line
));
2171 ca_laststate
.ddef
= NULL
;
2172 ca_laststate
.dopt
= NULL
;
2173 ca_laststate
.doff
= 0;
2176 } else if (state
.def
&& state
.def
->end
)
2177 endpat
= patcompile(state
.def
->end
, 0, NULL
);
2179 /* Copy the state into the global one. */
2183 if (cur
+ 1 == compcurrent
) {
2184 memcpy(&ca_laststate
, &state
, sizeof(state
));
2185 ca_laststate
.ddef
= NULL
;
2186 ca_laststate
.dopt
= NULL
;
2187 ca_laststate
.doff
= 0;
2188 } else if (cur
== compcurrent
&& !ca_laststate
.def
) {
2189 if ((ca_laststate
.def
= ddef
)) {
2190 ca_laststate
.singles
= state
.singles
;
2191 if (state
.curopt
&& state
.curopt
->type
== CAO_NEXT
) {
2192 ca_laststate
.ddef
= ddef
;
2193 ca_laststate
.dopt
= dopt
;
2194 ca_laststate
.def
= NULL
;
2195 ca_laststate
.opt
= 1;
2196 state
.curopt
->active
= 1;
2198 ca_laststate
.doff
= doff
;
2199 ca_laststate
.opt
= 0;
2202 ca_laststate
.def
= adef
;
2203 ca_laststate
.opt
= (!arglast
|| !multi
|| !*line
||
2204 *line
== '-' || *line
== '+');
2205 ca_laststate
.ddef
= NULL
;
2206 ca_laststate
.dopt
= NULL
;
2207 ca_laststate
.optbeg
= state
.nargbeg
;
2208 ca_laststate
.argbeg
= state
.restbeg
;
2209 ca_laststate
.argend
= state
.argend
;
2210 ca_laststate
.singles
= state
.singles
;
2211 ca_laststate
.oopt
= state
.oopt
;
2219 ca_laststate
.actopts
= 0;
2220 for (ptr
= d
->opts
; ptr
; ptr
= ptr
->next
)
2222 ca_laststate
.actopts
++;
2227 /* Build a colon-list from a list. */
2230 ca_colonlist(LinkList l
)
2237 for (n
= firstnode(l
); n
; incnode(n
)) {
2239 for (p
= (char *) getdata(n
); *p
; p
++)
2240 len
+= (*p
== ':' ? 2 : 1);
2242 ret
= q
= (char *) zalloc(len
);
2244 for (n
= firstnode(l
); n
;) {
2245 for (p
= (char *) getdata(n
); *p
; p
++) {
2262 * This function adds the current set of descriptions, actions,
2263 * and subcontext descriptions to the given linked list for passing
2264 * up in comparguments -D and comparguments -L. opt is the
2265 * option string (may be NULL if this isn't an option argument) and arg the
2266 * argument structure (either an option argument or a normal argument
2267 * as determined by arg->type).
2271 ca_set_data(LinkList descr
, LinkList act
, LinkList subc
,
2272 char *opt
, Caarg arg
, Caopt optdef
, int single
)
2274 LinkNode dnode
, anode
;
2275 char nbuf
[40], *buf
;
2276 int restr
= 0, onum
, miss
= 0, rest
, oopt
= 1, lopt
= 0, addopt
;
2280 addopt
= (opt
? 0 : ca_laststate
.oopt
);
2282 for (; arg
&& (opt
|| (arg
->num
< 0 ||
2283 (arg
->min
<= ca_laststate
.nth
+ addopt
&&
2284 arg
->num
>= ca_laststate
.nth
)));) {
2285 lopt
= (arg
->type
== CAA_OPT
);
2286 if (!opt
&& !lopt
&& oopt
> 0)
2289 for (dnode
= firstnode(descr
), anode
= firstnode(act
);
2290 dnode
; incnode(dnode
), incnode(anode
))
2291 if (!strcmp((char *) getdata(dnode
), arg
->descr
) &&
2292 !strcmp((char *) getdata(anode
), arg
->action
))
2296 addlinknode(descr
, arg
->descr
);
2297 addlinknode(act
, arg
->action
);
2300 if ((restr
= (arg
->type
== CAA_RARGS
)))
2301 restrict_range(ca_laststate
.optbeg
, ca_laststate
.argend
);
2302 else if ((restr
= (arg
->type
== CAA_RREST
)))
2303 restrict_range(ca_laststate
.argbeg
, ca_laststate
.argend
);
2306 buf
= (char *) zhalloc((arg
->set
? strlen(arg
->set
) : 0) +
2307 strlen(arg
->opt
) + 40);
2308 if (arg
->num
> 0 && arg
->type
< CAA_REST
)
2309 sprintf(buf
, "%soption%s-%d",
2310 (arg
->set
? arg
->set
: ""), arg
->opt
, arg
->num
);
2312 sprintf(buf
, "%soption%s-rest",
2313 (arg
->set
? arg
->set
: ""), arg
->opt
);
2314 } else if (arg
->num
> 0) {
2315 sprintf(nbuf
, "argument-%d", arg
->num
);
2316 buf
= (arg
->set
? dyncat(arg
->set
, nbuf
) : dupstring(nbuf
));
2318 buf
= (arg
->set
? dyncat(arg
->set
, "argument-rest") :
2319 dupstring("argument-rest"));
2321 addlinknode(subc
, buf
);
2324 * If this is an argument to an option, and the option definition says
2325 * the argument to the option is required and in the following
2326 * (i.e. this) word, then it must match what we've just told it to
2327 * match---don't try to match normal arguments.
2329 * This test may be too stringent for what we need, or it
2330 * may be too loose; I've simply tweaked it until it gets
2331 * the case above right.
2333 if (arg
->type
== CAA_NORMAL
&&
2334 opt
&& optdef
&& optdef
->type
== CAO_NEXT
)
2340 if (arg
->num
>= 0 && !arg
->next
&& miss
)
2341 arg
= (ca_laststate
.d
->rest
&& ca_laststate
.d
->rest
->active
?
2342 ca_laststate
.d
->rest
: NULL
);
2345 rest
= (onum
!= arg
->min
&& onum
== ca_laststate
.nth
);
2346 if ((arg
= arg
->next
)) {
2347 if (arg
->num
!= onum
+ 1)
2349 } else if (rest
|| (oopt
> 0 && !opt
)) {
2350 arg
= (ca_laststate
.d
->rest
&& ca_laststate
.d
->rest
->active
?
2351 ca_laststate
.d
->rest
: NULL
);
2361 if (!single
&& opt
&& (lopt
|| ca_laststate
.oopt
)) {
2363 arg
= ca_get_arg(ca_laststate
.d
, ca_laststate
.nth
);
2367 if (!opt
&& oopt
> 0) {
2369 arg
= (ca_laststate
.d
->rest
&& ca_laststate
.d
->rest
->active
?
2370 ca_laststate
.d
->rest
: NULL
);
2377 bin_comparguments(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
2380 Castate lstate
= &ca_laststate
;
2382 if (incompfunc
!= 1) {
2383 zwarnnam(nam
, "can only be called from completion function");
2386 if (args
[0][0] != '-' || !args
[0][1] || args
[0][2]) {
2387 zwarnnam(nam
, "invalid argument: %s", args
[0]);
2390 if (args
[0][1] != 'i' && args
[0][1] != 'I' && !ca_parsed
) {
2391 zwarnnam(nam
, "no parsed state");
2394 switch (args
[0][1]) {
2395 case 'i': min
= 2; max
= -1; break;
2396 case 'D': min
= 3; max
= 3; break;
2397 case 'O': min
= 4; max
= 4; break;
2398 case 'L': min
= 3; max
= 4; break;
2399 case 's': min
= 1; max
= 1; break;
2400 case 'M': min
= 1; max
= 1; break;
2401 case 'a': min
= 0; max
= 0; break;
2402 case 'W': min
= 2; max
= 2; break;
2403 case 'n': min
= 1; max
= 1; break;
2405 zwarnnam(nam
, "invalid option: %s", args
[0]);
2408 n
= arrlen(args
) - 1;
2410 zwarnnam(nam
, "not enough arguments");
2412 } else if (max
>= 0 && n
> max
) {
2413 zwarnnam(nam
, "too many arguments");
2416 switch (args
[0][1]) {
2418 /* This initialises the internal data structures. Arguments are the
2419 * auto-description string, the optional -s, -S, -A and -M options
2420 * given to _arguments and the specs. */
2421 if (compcurrent
> 1 && compwords
[0]) {
2423 int cap
= ca_parsed
, multi
, first
= 1, use
, ret
= 0;
2424 LinkList cax
= ca_xor
, nx
;
2426 Castate states
= NULL
, sp
;
2432 if (!(def
= get_cadef(nam
, args
+ 1)))
2435 multi
= !!def
->snext
;
2437 ca_xor
= (multi
? newlinklist() : NULL
);
2440 use
= !ca_parse_line(def
, multi
, first
);
2443 while ((def
= def
->snext
)) {
2445 for (node
= firstnode(nx
); node
; incnode(node
)) {
2446 xor[0] = (char *) getdata(node
);
2447 if (!strcmp(xor[0], def
->sname
) ||
2448 ca_inactive(def
, xor, compcurrent
, 0, NULL
))
2457 sp
= (Castate
) zalloc(sizeof(*sp
));
2458 memcpy(sp
, &ca_laststate
, sizeof(*sp
));
2461 } else if (!use
&& !def
) {
2463 freecastate(&ca_laststate
);
2464 memcpy(&ca_laststate
, states
, sizeof(*sp
));
2466 zfree(states
, sizeof(*states
));
2475 ca_laststate
.snext
= states
;
2482 /* This returns the descriptions, actions and sub-contexts for the
2483 * things _arguments has to execute at this place on the line (the
2484 * sub-contexts are used as tags).
2485 * The return value is particularly important here, it says if
2486 * there are arguments to completely at all. */
2488 LinkList descr
, act
, subc
;
2490 int ign
= 0, ret
= 1;
2492 descr
= newlinklist();
2493 act
= newlinklist();
2494 subc
= newlinklist();
2501 if (!ign
&& lstate
->doff
> 0) {
2503 ignore_prefix(lstate
->doff
);
2505 ca_set_data(descr
, act
, subc
, arg
->opt
, arg
,
2506 lstate
->curopt
, (lstate
->doff
> 0));
2508 lstate
= lstate
->snext
;
2511 set_list_array(args
[1], descr
);
2512 set_list_array(args
[2], act
);
2513 set_list_array(args
[3], subc
);
2518 /* This returns the descriptions for the options in the arrays whose
2519 * names are given as arguments. The descriptions are strings in a
2520 * form usable by _describe. The return value says if there are any
2521 * options to be completed. */
2523 LinkList next
= newlinklist();
2524 LinkList direct
= newlinklist();
2525 LinkList odirect
= newlinklist();
2526 LinkList equal
= newlinklist(), l
;
2532 for (; lstate
; lstate
= lstate
->snext
) {
2533 if (lstate
->actopts
&&
2534 (lstate
->opt
|| (lstate
->doff
&& lstate
->def
) ||
2535 (lstate
->def
&& lstate
->def
->opt
&&
2536 (lstate
->def
->type
== CAA_OPT
||
2537 (lstate
->def
->type
>= CAA_RARGS
&&
2538 lstate
->def
->num
< 0)))) &&
2539 (!lstate
->def
|| lstate
->def
->type
< CAA_RARGS
||
2540 (lstate
->def
->type
== CAA_RARGS
?
2541 (lstate
->curpos
== lstate
->argbeg
+ 1) :
2542 (compcurrent
== 1)))) {
2544 for (p
= lstate
->d
->opts
; p
; p
= p
->next
) {
2545 if (p
->active
&& !p
->not) {
2547 case CAO_NEXT
: l
= next
; break;
2548 case CAO_DIRECT
: l
= direct
; break;
2549 case CAO_ODIRECT
: l
= odirect
; break;
2550 default: l
= equal
; break;
2553 char *n
= bslashcolon(p
->name
);
2554 int len
= strlen(n
) + strlen(p
->descr
) + 2;
2556 str
= (char *) zhalloc(len
);
2559 strcat(str
, p
->descr
);
2561 str
= bslashcolon(p
->name
);
2563 for (node
= firstnode(l
); node
; incnode(node
))
2564 if (!strcmp(str
, (char *) getdata(node
)))
2568 addlinknode(l
, str
);
2574 set_list_array(args
[1], next
);
2575 set_list_array(args
[2], direct
);
2576 set_list_array(args
[3], odirect
);
2577 set_list_array(args
[4], equal
);
2581 return (ca_laststate
.singles
? 2 : 1);
2584 /* This tests if the beginning of the current word matches an option.
2585 * It is for cases like `./configure --pre=/<TAB>' which should
2586 * complete to `--prefix=/...'. The options name isn't fully typed
2587 * and _arguments finds out that there is no option `--pre' and that
2588 * it should complete some argument to an option. It then uses -L
2589 * to find the option the argument is for. */
2591 LinkList descr
, act
, subc
;
2595 descr
= newlinklist();
2596 act
= newlinklist();
2597 subc
= newlinklist();
2600 opt
= ca_get_opt(lstate
->d
, args
[1], 1, NULL
);
2602 if (opt
&& opt
->args
) {
2604 ca_set_data(descr
, act
, subc
, opt
->name
, opt
->args
, opt
, 1);
2606 lstate
= lstate
->snext
;
2609 set_list_array(args
[2], descr
);
2610 set_list_array(args
[3], act
);
2611 set_list_array(args
[4], subc
);
2616 /* This returns zero if we are completing single letter options.
2617 * It also uses its argument as the name of a parameter and sets
2618 * that to a string describing the argument behaviour of the last
2619 * option in the current word so that we can get the auto-suffix
2621 for (; lstate
; lstate
= lstate
->snext
)
2622 if (lstate
->d
->single
&& lstate
->singles
&&
2625 /* let's try without, for the -W option of _arguments */
2630 ztrdup((lstate
->ddef
&& lstate
->dopt
) ?
2631 (lstate
->dopt
->type
== CAO_DIRECT
?
2633 ((lstate
->dopt
->type
== CAO_OEQUAL
||
2634 lstate
->dopt
->type
== CAO_EQUAL
) ?
2635 "equal" : "next")) : ""));
2640 /* This returns the match specs defined for the set of specs we are
2641 * using. Returned, as usual in a parameter whose name is given as
2643 setsparam(args
[1], ztrdup(ca_laststate
.d
->match
));
2646 /* This just sets the return value. To zero if there would be or
2647 * were any normal arguments to be completed. Used to decide if
2648 * _arguments should say `no arguments' or `no more arguments'. */
2649 for (; lstate
; lstate
= lstate
->snext
)
2650 if (lstate
->d
->args
|| lstate
->d
->rest
)
2654 /* This gets two parameter names as arguments. The first is set to
2655 * the current word sans any option prefixes handled by comparguments.
2656 * The second parameter is set to an array containing the options on
2657 * the line and their arguments. I.e. the stuff _arguments returns
2658 * to its caller in the `line' and `opt_args' parameters. */
2667 for (num
= 0, s
= lstate
; s
; s
= s
->snext
)
2668 num
+= countlinknodes(s
->args
);
2670 ret
= p
= zalloc((num
+ 1) * sizeof(char *));
2672 for (s
= lstate
; s
; s
= s
->snext
)
2673 for (n
= firstnode(s
->args
); n
; incnode(n
))
2674 *p
++ = ztrdup((char *) getdata(n
));
2677 setaparam(args
[1], ret
);
2679 for (num
= 0, s
= lstate
; s
; s
= s
->snext
)
2680 for (o
= s
->d
->opts
, a
= s
->oargs
; o
; o
= o
->next
, a
++)
2684 ret
= p
= zalloc((num
+ 1) * sizeof(char *));
2686 for (s
= lstate
; s
; s
= s
->snext
)
2687 for (o
= s
->d
->opts
, a
= s
->oargs
; o
; o
= o
->next
, a
++)
2689 *p
++ = (o
->set
? tricat(o
->set
, o
->name
, "") :
2691 *p
++ = ca_colonlist(*a
);
2695 sethparam(args
[2], ret
);
2700 * This returns the array index of the word where normal
2701 * arguments began. It uses optbeg rather than nargbeg
2702 * (the value used when parsing) because nargbeg is assigned
2703 * to optbeg in the returned value and nargbeg isn't
2706 * -->PLEASE DON'T ASK<--
2710 setiparam(args
[1], (zlong
)ca_laststate
.optbeg
+ !isset(KSHARRAYS
));
2716 /* Help for `_values'. */
2718 typedef struct cvdef
*Cvdef
;
2719 typedef struct cvval
*Cvval
;
2721 /* Definitions for _values. */
2724 char *descr
; /* global description */
2725 int hassep
; /* multiple values allowed */
2726 char sep
; /* separator character */
2727 char argsep
; /* argument separator */
2728 Cvdef next
; /* next in cache */
2729 Cvval vals
; /* value definitions */
2730 char **defs
; /* original strings */
2731 int ndefs
; /* number of ... */
2732 int lastt
; /* last time used */
2733 int words
; /* if to look at other words */
2736 /* One value definition. */
2740 char *name
; /* value name */
2741 char *descr
; /* description */
2742 char **xor; /* xor-list */
2743 int type
; /* CVV_* below */
2744 Caarg arg
; /* argument definition */
2745 int active
; /* still allowed */
2754 #define MAX_CVCACHE 8
2755 static Cvdef cvdef_cache
[MAX_CVCACHE
];
2769 for (p
= d
->vals
; p
; p
= n
) {
2776 zfree(p
, sizeof(*p
));
2778 zfree(d
, sizeof(*d
));
2782 /* Parse option definitions. */
2785 parse_cvdef(char *nam
, char **args
)
2790 char **oargs
= args
, sep
= '\0', asep
= '=', *name
, *descr
, *p
, *q
, **xor, c
;
2791 int xnum
, multi
, vtype
, hassep
= 0, words
= 0;
2793 while (args
&& args
[0] && args
[1] &&
2794 args
[0][0] == '-' &&
2795 (args
[0][1] == 's' || args
[0][1] == 'S' || args
[0][1] == 'w') &&
2798 if (args
[0][1] == 's') {
2802 } else if (args
[0][1] == 'S') {
2810 if (!args
[0] || !args
[1]) {
2811 zwarnnam(nam
, "not enough arguments");
2816 ret
= (Cvdef
) zalloc(sizeof(*ret
));
2817 ret
->descr
= ztrdup(descr
);
2818 ret
->hassep
= hassep
;
2823 ret
->defs
= zarrdup(oargs
);
2824 ret
->ndefs
= arrlen(oargs
);
2825 ret
->lastt
= time(0);
2828 for (valp
= &(ret
->vals
); *args
; args
++) {
2830 p
= dupstring(*args
);
2835 LinkList list
= newlinklist();
2839 while (*p
&& *p
!= ')') {
2840 for (p
++; inblank(*p
); p
++);
2844 for (q
= p
++; *p
&& *p
!= ')' && !inblank(*p
); p
++);
2851 addlinknode(list
, dupstring(q
));
2857 zwarnnam(nam
, "invalid argument: %s", *args
);
2860 xor = (char **) zalloc((xnum
+ 2) * sizeof(char *));
2861 for (node
= firstnode(list
), xp
= xor; node
; incnode(node
), xp
++)
2862 *xp
= ztrdup((char *) getdata(node
));
2863 xp
[0] = xp
[1] = NULL
;
2869 /* More than once allowed? */
2870 if ((multi
= (*p
== '*')))
2873 /* Skip option name. */
2875 for (name
= p
; *p
&& *p
!= ':' && *p
!= '['; p
++)
2876 if (*p
== '\\' && p
[1])
2879 if (hassep
&& !sep
&& name
+ bs
+ 1 < p
) {
2881 zwarnnam(nam
, "no multi-letter values with empty separator allowed");
2884 /* Optional description? */
2886 if ((c
= *p
) == '[') {
2888 for (descr
= ++p
; *p
&& *p
!= ']'; p
++)
2889 if (*p
== '\\' && p
[1])
2894 zwarnnam(nam
, "invalid value definition: %s", *args
);
2903 if (c
&& c
!= ':') {
2905 zwarnnam(nam
, "invalid value definition: %s", *args
);
2911 if (hassep
&& !sep
) {
2913 zwarnnam(nam
, "no value with argument with empty separator allowed");
2921 arg
= parse_caarg(0, 0, 0, 0, name
, &p
, NULL
);
2928 xor = (char **) zalloc(2 * sizeof(char *));
2931 xor[xnum
] = ztrdup(name
);
2933 *valp
= val
= (Cvval
) zalloc(sizeof(*val
));
2934 valp
= &((*valp
)->next
);
2937 val
->name
= ztrdup(name
);
2938 val
->descr
= ztrdup(descr
);
2946 /* Get the definition from the cache or newly built. */
2949 get_cvdef(char *nam
, char **args
)
2951 Cvdef
*p
, *min
, new;
2952 int i
, na
= arrlen(args
);
2954 for (i
= MAX_CVCACHE
, p
= cvdef_cache
, min
= NULL
; *p
&& i
--; p
++)
2955 if (*p
&& na
== (*p
)->ndefs
&& arrcmp(args
, (*p
)->defs
)) {
2956 (*p
)->lastt
= time(0);
2959 } else if (!min
|| !*p
|| (*p
)->lastt
< (*min
)->lastt
)
2963 if ((new = parse_cvdef(nam
, args
))) {
2970 /* Get the definition for a value. */
2973 cv_get_val(Cvdef d
, char *name
)
2977 for (p
= d
->vals
; p
; p
= p
->next
)
2978 if (!strcmp(name
, p
->name
))
2985 cv_quote_get_val(Cvdef d
, char *name
)
2990 name
= dupstring(name
);
2993 parse_subst_string(name
);
2998 return cv_get_val(d
, name
);
3001 /* Handle a xor list. */
3004 cv_inactive(Cvdef d
, char **xor)
3010 if ((val
= cv_get_val(d
, *xor)))
3024 static struct cvstate cv_laststate
;
3025 static int cv_parsed
= 0, cv_alloced
= 0;
3027 /* Get the next value in the string. Return it's definition and update the
3028 * sp pointer to point to the end of the value (plus argument, if any).
3029 * If there is no next value, the string pointer is set to null. In any
3030 * case ap will point to the beginning of the argument or will be a null
3031 * pointer if there is no argument.
3035 cv_next(Cvdef d
, char **sp
, char **ap
)
3045 if ((d
->hassep
&& !d
->sep
) || !d
->argsep
) {
3046 char sav
, ec
, *v
= s
, *os
;
3048 ec
= ((d
->hassep
&& d
->sep
) ? d
->sep
: d
->argsep
);
3053 if ((r
= cv_quote_get_val(d
, v
))) {
3059 } while (*s
&& *s
!= ec
);
3063 if (d
->hassep
&& d
->sep
) {
3064 if ((s
= strchr(s
, d
->sep
)))
3070 if (d
->argsep
&& *os
== d
->argsep
) {
3073 } else if (r
&& r
->type
!= CVV_NOARG
)
3080 } else if (d
->hassep
) {
3081 char *ns
= strchr(s
, d
->sep
), *as
= 0, *sap
, sav
= 0;
3084 if (d
->argsep
&& (as
= strchr(s
, d
->argsep
)) && (!ns
|| as
<= ns
)) {
3086 ns
= strchr(as
+ 1, d
->sep
);
3097 if ((!(r
= cv_quote_get_val(d
, s
)) || r
->type
== CVV_NOARG
) && skip
)
3103 *sp
= ((!ns
|| (ns
== as
&& r
&& r
->type
!= CVV_NOARG
)) ? NULL
: ns
+ 1);
3107 char *as
= strchr(s
, d
->argsep
), *sap
, sav
= 0;
3119 r
= cv_quote_get_val(d
, s
);
3128 /* Parse the current word. */
3131 cv_parse_word(Cvdef d
)
3134 struct cvstate state
;
3135 char *str
, *arg
= NULL
, *pign
= compprefix
;
3139 freelinklist(cv_laststate
.vals
, freestr
);
3141 for (val
= d
->vals
; val
; val
= val
->next
)
3147 state
.vals
= (LinkList
) znewlinklist();
3151 if (d
->words
&& compwords
[0]) {
3154 for (i
= 1; compwords
[i
]; i
++)
3155 if (i
!= compcurrent
- 1)
3156 for (str
= compwords
[i
]; str
&& *str
; ) {
3157 if ((val
= cv_next(d
, &str
, &arg
))) {
3158 zaddlinknode(state
.vals
, ztrdup(val
->name
));
3166 zaddlinknode(state
.vals
, ztrdup(arg
));
3170 zaddlinknode(state
.vals
, ztrdup(""));
3172 if (i
+ 1 < compcurrent
)
3173 cv_inactive(d
, val
->xor);
3180 for (str
= compprefix
; str
&& *str
; ) {
3181 if ((val
= cv_next(d
, &str
, &arg
))) {
3182 zaddlinknode(state
.vals
, ztrdup(val
->name
));
3188 zaddlinknode(state
.vals
, ztrdup(arg
));
3191 zaddlinknode(state
.vals
, tricat(arg
, compsuffix
, ""));
3195 zaddlinknode(state
.vals
, ztrdup(""));
3197 cv_inactive(d
, val
->xor);
3206 if (val
&& arg
&& !str
)
3207 state
.def
= val
->arg
;
3209 if (!nosfx
&& d
->hassep
) {
3213 ignore_prefix(pign
- compprefix
);
3215 if (!d
->sep
&& (!val
|| val
->type
== CVV_NOARG
)) {
3216 ign
= strlen(compsuffix
);
3220 char *ns
= strchr(compsuffix
, d
->sep
), *as
;
3222 if (d
->argsep
&& (as
= strchr(compsuffix
, d
->argsep
)) &&
3223 (!ns
|| as
<= ns
)) {
3226 ign
= (ns
? strlen(ns
) : 0);
3228 more
= (ns
? ns
+ 1 : NULL
);
3229 } else if (d
->argsep
) {
3232 if ((as
= strchr(compsuffix
, d
->argsep
)))
3236 more
= dupstring(more
);
3241 while (more
&& *more
) {
3242 if ((val
= cv_next(d
, &more
, &arg
))) {
3243 zaddlinknode(state
.vals
, ztrdup(val
->name
));
3246 char sav
= more
[-1];
3249 zaddlinknode(state
.vals
, ztrdup(arg
));
3252 zaddlinknode(state
.vals
, tricat(arg
, compsuffix
, ""));
3256 zaddlinknode(state
.vals
, ztrdup(""));
3258 cv_inactive(d
, val
->xor);
3262 ignore_prefix(arg
- compprefix
);
3264 ignore_prefix(pign
- compprefix
);
3266 memcpy(&cv_laststate
, &state
, sizeof(state
));
3270 bin_compvalues(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
3274 if (incompfunc
!= 1) {
3275 zwarnnam(nam
, "can only be called from completion function");
3278 if (args
[0][0] != '-' || !args
[0][1] || args
[0][2]) {
3279 zwarnnam(nam
, "invalid argument: %s", args
[0]);
3282 if (args
[0][1] != 'i' && !cv_parsed
) {
3283 zwarnnam(nam
, "no parsed state");
3286 switch (args
[0][1]) {
3287 case 'i': min
= 2; max
= -1; break;
3288 case 'D': min
= 2; max
= 2; break;
3289 case 'C': min
= 1; max
= 1; break;
3290 case 'V': min
= 3; max
= 3; break;
3291 case 's': min
= 1; max
= 1; break;
3292 case 'S': min
= 1; max
= 1; break;
3293 case 'd': min
= 1; max
= 1; break;
3294 case 'L': min
= 3; max
= 4; break;
3295 case 'v': min
= 1; max
= 1; break;
3297 zwarnnam(nam
, "invalid option: %s", args
[0]);
3300 n
= arrlen(args
) - 1;
3302 zwarnnam(nam
, "not enough arguments");
3304 } else if (max
>= 0 && n
> max
) {
3305 zwarnnam(nam
, "too many arguments");
3308 switch (args
[0][1]) {
3310 /* This initialises the internal data structures. The arguments are
3311 * just the arguments that were given to _values itself. */
3313 Cvdef def
= get_cvdef(nam
, args
+ 1);
3314 int cvp
= cv_parsed
;
3330 /* This returns the description and action to use if we are at
3331 * a place where some action has to be used at all. In that case
3332 * zero is returned and non-zero otherwise. */
3334 Caarg arg
= cv_laststate
.def
;
3337 setsparam(args
[1], ztrdup(arg
->descr
));
3338 setsparam(args
[2], ztrdup(arg
->action
));
3345 /* This returns the sub-context (i.e.: the tag) to use when executing
3348 Caarg arg
= cv_laststate
.def
;
3351 setsparam(args
[1], ztrdup(arg
->opt
));
3358 /* This is what -O is for comparguments: it returns (in three arrays)
3359 * the values for values without arguments, with arguments and with
3360 * optional arguments (so that we can get the auto-suffixes right).
3361 * As for comparguments, the strings returned are usable for _describe. */
3363 LinkList noarg
= newlinklist();
3364 LinkList arg
= newlinklist();
3365 LinkList opt
= newlinklist(), l
;
3369 for (p
= cv_laststate
.d
->vals
; p
; p
= p
->next
) {
3372 case CVV_NOARG
: l
= noarg
; break;
3373 case CVV_ARG
: l
= arg
; break;
3374 default: l
= opt
; break;
3377 int len
= strlen(p
->name
) + strlen(p
->descr
) + 2;
3379 str
= (char *) zhalloc(len
);
3380 strcpy(str
, p
->name
);
3382 strcat(str
, p
->descr
);
3385 addlinknode(l
, str
);
3388 set_list_array(args
[1], noarg
);
3389 set_list_array(args
[2], arg
);
3390 set_list_array(args
[3], opt
);
3395 /* This returns the value separator, if any, and sets the return
3396 * value to say if there is such a separator. */
3397 if (cv_laststate
.d
->hassep
) {
3400 tmp
[0] = cv_laststate
.d
->sep
;
3402 setsparam(args
[1], ztrdup(tmp
));
3408 /* Like -s, but for the separator between values and their arguments. */
3412 tmp
[0] = cv_laststate
.d
->argsep
;
3414 setsparam(args
[1], ztrdup(tmp
));
3418 /* This returns the description string (first argument to _values)
3419 * which is passed down to _describe. */
3420 setsparam(args
[1], ztrdup(cv_laststate
.d
->descr
));
3423 /* Almost the same as for comparguments. This gets a value name
3424 * and returns the description and action of its first argument, if
3425 * any. The rest (prefix matching) is in _values. Return non-zero
3426 * if there is no such option. */
3428 Cvval val
= cv_get_val(cv_laststate
.d
, args
[1]);
3430 if (val
&& val
->arg
) {
3431 setsparam(args
[2], val
->arg
->descr
);
3432 setsparam(args
[3], val
->arg
->action
);
3435 setsparam(args
[4], ztrdup(val
->name
));
3442 /* Again, as for comparguments. This returns the values and their
3443 * arguments as an array which will be stored in val_args in _values. */
3444 if (cv_laststate
.vals
) {
3447 ret
= zlinklist2array(cv_laststate
.vals
);
3448 sethparam(args
[1], ret
);
3458 comp_quote(char *str
, int prefix
)
3463 if ((x
= (prefix
&& *str
== '=')))
3466 ret
= quotestring(str
, NULL
, *compqstack
);
3475 bin_compquote(char *nam
, char **args
, Options ops
, UNUSED(int func
))
3481 if (incompfunc
!= 1) {
3482 zwarnnam(nam
, "can only be called from completion function");
3485 /* Anything to do? */
3487 if (!compqstack
|| !*compqstack
)
3490 /* For all parameters given... */
3492 while ((name
= *args
++)) {
3493 name
= dupstring(name
);
3495 if ((v
= getvalue(&vbuf
, &name
, 0))) {
3496 switch (PM_TYPE(v
->pm
->node
.flags
)) {
3498 setstrvalue(v
, ztrdup(comp_quote(getstrvalue(v
),
3499 OPT_ISSET(ops
,'p'))));
3503 char **val
= v
->pm
->gsu
.a
->getfn(v
->pm
);
3504 char **new = (char **) zalloc((arrlen(val
) + 1) *
3508 for (; *val
; val
++, p
++)
3509 *p
= ztrdup(comp_quote(*val
, OPT_ISSET(ops
,'p')));
3512 setarrvalue(v
, new);
3516 zwarnnam(nam
, "invalid parameter type: %s", args
[-1]);
3519 zwarnnam(nam
, "unknown parameter: %s", args
[-1]);
3527 typedef struct ctags
*Ctags
;
3528 typedef struct ctset
*Ctset
;
3530 /* A bunch of tag sets. */
3533 char **all
; /* all tags offered */
3534 char *context
; /* the current context */
3535 int init
; /* not yet used */
3536 Ctset sets
; /* the tag sets */
3543 char **tags
; /* the tags */
3544 char *tag
; /* last tag checked for -A */
3545 char **ptr
; /* ptr into tags for -A */
3548 /* Array of tag-set infos. Index is the locallevel. */
3550 #define MAX_TAGS 256
3551 static Ctags comptags
[MAX_TAGS
];
3553 /* locallevel at last comptags -i */
3555 static int lasttaglevel
;
3568 zfree(s
, sizeof(*s
));
3582 zfree(t
, sizeof(*t
));
3586 /* Set the tags for the current local level. */
3589 settags(int level
, char **tags
)
3593 if (comptags
[level
])
3594 freectags(comptags
[level
]);
3596 comptags
[level
] = t
= (Ctags
) zalloc(sizeof(*t
));
3598 t
->all
= zarrdup(tags
+ 1);
3599 t
->context
= ztrdup(*tags
);
3604 /* Check if an array contains a string. */
3608 arrcontains(char **a
, char *s
, int colon
)
3614 for (p
= s
, q
= *a
++; *p
&& *q
&& *p
!= ':' && *q
!= ':'; p
++, q
++)
3617 if ((!*p
|| *p
== ':') && (!*q
|| *q
== ':'))
3619 } else if (!strcmp(*a
++, s
))
3626 bin_comptags(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
3628 int min
, max
, n
, level
;
3630 if (incompfunc
!= 1) {
3631 zwarnnam(nam
, "can only be called from completion function");
3634 if (args
[0][0] != '-' || !args
[0][1] ||
3635 (args
[0][2] && (args
[0][2] != '-' || args
[0][3]))) {
3636 zwarnnam(nam
, "invalid argument: %s", args
[0]);
3639 level
= locallevel
- (args
[0][2] ? 1 : 0);
3640 if (level
>= MAX_TAGS
) {
3641 zwarnnam(nam
, "nesting level too deep");
3644 if (args
[0][1] != 'i' && args
[0][1] != 'I' && !comptags
[level
]) {
3645 zwarnnam(nam
, "no tags registered");
3648 switch (args
[0][1]) {
3649 case 'i': min
= 2; max
= -1; break;
3650 case 'C': min
= 1; max
= 1; break;
3651 case 'T': min
= 0; max
= 0; break;
3652 case 'N': min
= 0; max
= 0; break;
3653 case 'R': min
= 1; max
= 1; break;
3654 case 'S': min
= 1; max
= 1; break;
3655 case 'A': min
= 2; max
= 3; break;
3657 zwarnnam(nam
, "invalid option: %s", args
[0]);
3660 n
= arrlen(args
) - 1;
3662 zwarnnam(nam
, "not enough arguments");
3664 } else if (max
>= 0 && n
> max
) {
3665 zwarnnam(nam
, "too many arguments");
3668 switch (args
[0][1]) {
3670 settags(level
, args
+ 1);
3671 lasttaglevel
= level
;
3674 setsparam(args
[1], ztrdup(comptags
[level
]->context
));
3677 return !comptags
[level
]->sets
;
3682 if (comptags
[level
]->init
)
3683 comptags
[level
]->init
= 0;
3684 else if ((s
= comptags
[level
]->sets
)) {
3685 comptags
[level
]->sets
= s
->next
;
3689 return !comptags
[level
]->sets
;
3695 return !((s
= comptags
[level
]->sets
) &&
3696 arrcontains(s
->tags
, args
[1], 1));
3702 if (comptags
[level
] && (s
= comptags
[level
]->sets
)) {
3703 char **q
, *v
= NULL
;
3704 int l
= strlen(args
[1]);
3706 if (!s
->tag
|| strcmp(s
->tag
, args
[1])) {
3708 s
->tag
= ztrdup(args
[1]);
3711 for (q
= s
->ptr
; *q
; q
++) {
3712 if (strpfx(args
[1], *q
)) {
3716 } else if ((*q
)[l
] == ':') {
3728 setsparam(args
[2], ztrdup(*v
== '-' ? dyncat(args
[1], v
) : v
));
3730 char *r
= dupstring(*q
), *p
;
3732 for (p
= r
+ (v
- *q
); *p
&& *p
!= ':'; p
++);
3735 setsparam(args
[3], ztrdup(r
));
3742 if (comptags
[level
]->sets
) {
3745 ret
= zarrdup(comptags
[level
]->sets
->tags
);
3746 setaparam(args
[1], ret
);
3756 bin_comptry(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
3758 if (incompfunc
!= 1) {
3759 zwarnnam(nam
, "can only be called from completion function");
3762 if (!lasttaglevel
|| !comptags
[lasttaglevel
]) {
3763 zwarnnam(nam
, "no tags registered");
3767 if (!strcmp(*args
, "-m")) {
3768 char *s
, *p
, *q
, *c
, **all
= comptags
[lasttaglevel
]->all
;
3769 LinkList list
= newlinklist();
3773 while ((s
= *++args
)) {
3775 while (*s
&& iblank(*s
))
3777 for (p
= q
= s
, c
= NULL
; *s
&& !inblank(*s
); s
++) {
3778 if (!c
&& *s
== ':')
3780 if (*s
== '\\' && s
[1])
3793 qqq
= qq
= dupstring(q
);
3795 if (*qqq
== '\\' && qqq
[1])
3797 else if (*qqq
== '{')
3799 else if (*qqq
== '}')
3801 else if (*qqq
== ',')
3806 if (haswilds(qq
) || hasbraces(qq
)) {
3808 LinkNode bnode
, node
;
3809 LinkList blist
= newlinklist();
3811 addlinknode(blist
, qq
);
3812 for (bnode
= firstnode(blist
); bnode
; incnode(bnode
))
3813 while (hasbraces(getdata(bnode
)))
3814 xpandbraces(blist
, &bnode
);
3816 for (bnode
= firstnode(blist
); bnode
; incnode(bnode
)) {
3817 qq
= (char *) getdata(bnode
);
3818 if ((prog
= patcompile(qq
, PAT_STATIC
, NULL
))) {
3820 int l
= (c
? strlen(c
+ 1) + 2 : 1), al
;
3822 for (a
= all
; *a
; a
++) {
3823 for (node
= firstnode(list
); node
;
3827 for (as
= *a
, ls
= (char *) getdata(node
);
3828 *as
&& *ls
&& *ls
!= ':'; as
++, ls
++)
3831 if (!*as
&& (!*ls
|| *ls
== ':'))
3836 if (pattry(prog
, *a
)) {
3837 n
= (char *) zhalloc((al
= strlen(*a
)) + l
);
3841 strcpy(n
+ al
+ 1, c
+ 1);
3843 addlinknode(list
, n
);
3849 } else if (arrcontains(all
, q
, 0)) {
3850 for (set
= comptags
[lasttaglevel
]->sets
; set
;
3852 if (arrcontains(set
->tags
, q
, 0))
3855 addlinknode(list
, q
);
3866 set
= (Ctset
) zalloc(sizeof(*set
));
3868 set
->tags
= zlinklist2array(list
);
3873 if ((l
= comptags
[lasttaglevel
]->sets
)) {
3879 comptags
[lasttaglevel
]->sets
= set
;
3883 char **p
, **q
, **all
;
3886 if ((sep
= !strcmp(*args
, "-s")))
3889 for (p
= q
= args
, all
= comptags
[lasttaglevel
]->all
; *p
; p
++)
3890 if (arrcontains(all
, *p
, 1)) {
3893 for (s
= comptags
[lasttaglevel
]->sets
; s
; s
= s
->next
)
3894 if (arrcontains(s
->tags
, *p
, 0))
3906 Ctset s
= (Ctset
) zalloc(sizeof(*s
)), l
;
3911 s
->tags
= zarrdup(dummy
);
3913 s
->tags
= zarrdup(args
);
3918 if ((l
= comptags
[lasttaglevel
]->sets
)) {
3924 comptags
[lasttaglevel
]->sets
= s
;
3925 } while (sep
&& *args
);
3932 #define PATH_MAX2 (PATH_MAX * 2)
3935 cfp_test_exact(LinkList names
, char **accept
, char *skipped
)
3937 char buf
[PATH_MAX2
+ 1], *suf
, *p
;
3938 int l
, sl
, found
= 0;
3941 LinkList ret
= newlinklist(), alist
= NULL
;
3943 if ((!(compprefix
&& *compprefix
) && !(compsuffix
&& *compsuffix
)) ||
3944 (!accept
|| !*accept
||
3945 ((!strcmp(*accept
, "false") || !strcmp(*accept
, "no") ||
3946 !strcmp(*accept
, "off") || !strcmp(*accept
, "0")) && !accept
[1])))
3950 (strcmp(*accept
, "true") && strcmp(*accept
, "yes") &&
3951 strcmp(*accept
, "on") && strcmp(*accept
, "1"))) {
3954 alist
= newlinklist();
3956 for (; (p
= *accept
); accept
++) {
3957 if (*p
== '*' && !p
[1]) {
3961 tokenize(p
= dupstring(p
));
3962 if ((prog
= patcompile(p
, 0, NULL
)))
3963 addlinknode(alist
, prog
);
3966 sl
= strlen(skipped
) + (compprefix
? strlen(compprefix
) : 0) +
3967 (compsuffix
? strlen(compsuffix
) : 0);
3972 suf
= dyncat(skipped
, rembslash(dyncat(compprefix
, compsuffix
)));
3974 for (node
= firstnode(names
); node
; incnode(node
)) {
3975 l
= strlen(p
= (char *) getdata(node
));
3976 if (l
+ sl
< PATH_MAX2
) {
3978 strcpy(buf
+ l
, suf
);
3980 if (!ztat(buf
, &st
, 0)) {
3984 for (anode
= firstnode(alist
); anode
; incnode(anode
))
3985 if (pattry((Patprog
) getdata(anode
), buf
))
3992 addlinknode(ret
, dupstring(buf
));
3996 return (found
? ret
: NULL
);
4001 * This code constructs (from heap) and returns a string that
4002 * corresponds to a series of matches; when compiled as a pattern, at
4003 * each position it matches either the character from the string "add"
4004 * or the corresponding single-character match from the set of matchers.
4005 * To take a simple case, if add is "a" and the single matcher for the
4006 * character position matches "[0-9]", the pattern returned is "[0-9a]".
4007 * We take account of equivalences between the word and line, too.
4009 * As there are virtually no comments in this file, I don't really
4010 * know why we're doing this, but it's to do with a matcher which
4011 * is passed as an argument to the utility compfiles -p/-P.
4014 cfp_matcher_range(Cmatcher
*ms
, char *add
)
4018 char *ret
= NULL
, *p
= NULL
, *adds
= add
;
4021 * Do this twice: once to work out the length of the
4022 * string in len, the second time to build it in ret.
4023 * This is probably worthwhile because otherwise memory
4024 * management is difficult.
4028 for (mp
= ms
; *add
; ) {
4032 addlen
= MB_METACHARLENCONV(add
, &addc
);
4033 #ifdef MULTIBYTE_SUPPORT
4035 addc
= (wchar_t)(*p
== Meta
? p
[1] ^ 32 : *p
);
4040 * No matcher, so just match the character
4043 * TODO: surely this needs quoting if it's a
4047 memcpy(p
, add
, addlen
);
4051 } else if (m
->flags
& CMF_RIGHT
) {
4053 * Right-anchored: match anything followed
4054 * by the character itself.
4058 /* TODO: quote again? */
4059 memcpy(p
, add
, addlen
);
4064 /* The usual set of matcher possibilities. */
4066 if (m
->line
->tp
== CPAT_EQUIV
&&
4067 m
->word
->tp
== CPAT_EQUIV
) {
4069 * Genuine equivalence. Add the character to match
4070 * and the equivalent character from the word
4073 * TODO: we could be more careful here with special
4074 * cases as we are in the basic character class
4079 memcpy(p
, add
, addlen
);
4083 if (PATMATCHRANGE(m
->line
->u
.str
, addc
, &ind
, &mt
)) {
4085 * Find the equivalent match for ind in the
4088 if ((ind
= pattern_match_equivalence
4089 (m
->word
, ind
, mt
, addc
)) != CHR_INVALID
) {
4097 len
+= imeta(ind
) ? 2 : 1;
4107 switch (m
->word
->tp
) {
4110 * TODO: the old logic implies that we need to
4111 * match *add, i.e. it should be deleted from
4112 * the set of character's we're not allowed to
4113 * match. That's too much like hard work for
4114 * now. Indeed, in general it's impossible
4115 * without trickery. Consider *add == 'A',
4116 * range == "[^[:upper:]]": we would have to
4117 * resort to something like "(A|[^[:upper:]])";
4118 * and in an expression like that *add may or
4119 * may not need backslashing. So we're deep
4120 * into see-if-we-can-get-away-without
4129 * Convert the compiled range string back
4130 * to an ordinary string.
4133 pattern_range_to_string(m
->word
->u
.str
, p
);
4134 DPUTS(!newlen
, "empty character range");
4144 * If there is an equivalence only on one
4145 * side it's not equivalent to anything.
4146 * Treat it as an ordinary character class.
4155 * We needed to add *add specially only if
4156 * it is not covered by the range. This
4157 * is necessary for correct syntax---consider
4158 * if *add is ] and ] is also the first
4159 * character in the range.
4161 addadd
= !pattern_match1(m
->word
, addc
, &mt
);
4162 if (addadd
&& *add
== ']') {
4168 if (m
->word
->tp
== CPAT_CHAR
) {
4170 * The matcher just matches a single
4171 * character, but we need to be able
4172 * to match *add, too, hence we do
4176 if (imeta(m
->word
->u
.chr
)) {
4178 *p
++ = m
->word
->u
.chr
^ 32;
4180 *p
++ = m
->word
->u
.chr
;
4182 len
+= imeta(m
->word
->u
.chr
) ? 2 : 1;
4185 * Convert the compiled range string back
4186 * to an ordinary string.
4189 pattern_range_to_string(m
->word
->u
.str
, p
);
4190 DPUTS(!newlen
, "empty character range");
4196 if (addadd
&& *add
!= ']') {
4198 memcpy(p
, add
, addlen
);
4225 p
= ret
= zhalloc(len
+ 1);
4232 cfp_matcher_pats(char *matcher
, char *add
)
4234 Cmatcher m
= parse_cmatcher(NULL
, matcher
);
4236 if (m
&& m
!= pcm_err
) {
4238 int al
= strlen(add
), zl
= ztrlen(add
), tl
, cl
;
4239 VARARR(Cmatcher
, ms
, zl
);
4244 memset(ms
, 0, zl
* sizeof(Cmatcher
));
4246 for (; m
&& *add
; m
= m
->next
) {
4248 if (!(m
->flags
& (CMF_LEFT
|CMF_RIGHT
))) {
4249 if (m
->llen
== 1 && m
->wlen
== 1) {
4250 for (tmp
= add
, tl
= al
, mp
= ms
; tl
; ) {
4251 if (pattern_match(m
->line
, tmp
, NULL
, NULL
)) {
4259 cl
= (*tmp
== Meta
) ? 2 : 1;
4268 } else if (m
->flags
& CMF_RIGHT
) {
4269 if (m
->wlen
< 0 && !m
->llen
&& m
->ralen
== 1) {
4270 for (tmp
= add
, tl
= al
, mp
= ms
; tl
; ) {
4271 if (pattern_match(m
->right
, tmp
, NULL
, NULL
)) {
4272 if (*mp
|| (tmp
== add
&& *tmp
== '.')) {
4279 cl
= (*tmp
== Meta
) ? 2 : 1;
4284 } else if (m
->llen
) {
4299 for (tmp
= add
, tl
= al
; tl
>= stopl
; ) {
4300 if (pattern_match(stopp
, tmp
, NULL
, NULL
)) {
4305 cl
= (*tmp
== Meta
) ? 2 : 1;
4311 return cfp_matcher_range(ms
, add
);
4317 cfp_opt_pats(char **pats
, char *matcher
)
4319 char *add
, **p
, *q
, *t
, *s
;
4321 if (!compprefix
|| !*compprefix
)
4324 if (comppatmatch
&& *comppatmatch
) {
4325 tokenize(t
= rembslash(dyncat(compprefix
, compsuffix
)));
4330 add
= (char *) zhalloc(strlen(compprefix
) * 2 + 1);
4331 for (s
= compprefix
, t
= add
; *s
; s
++) {
4332 if (*s
!= '\\' || !s
[1] || s
[1] == '*' || s
[1] == '?' ||
4333 s
[1] == '<' || s
[1] == '>' || s
[1] == '(' || s
[1] == ')' ||
4334 s
[1] == '[' || s
[1] == ']' || s
[1] == '|' || s
[1] == '#' ||
4335 s
[1] == '^' || s
[1] == '~' || s
[1] == '=') {
4336 if ((s
== compprefix
|| s
[-1] != '\\') &&
4337 (*s
== '*' || *s
== '?' || *s
== '<' || *s
== '>' ||
4338 *s
== '(' || *s
== ')' || *s
== '[' || *s
== ']' ||
4339 *s
== '|' || *s
== '#' || *s
== '^' || *s
== '~' ||
4346 for (p
= pats
; *add
&& (q
= *p
); p
++) {
4349 t
= q
+ strlen(q
) - 1;
4351 for (s
= t
--; t
> q
; t
--)
4352 if (*t
== ')' || *t
== '|' || *t
== '~' || *t
== '(')
4354 if (t
!= q
&& *t
== '(')
4357 for (; *q
&& *add
; q
++) {
4358 if (*q
== '\\' && q
[1]) {
4359 for (s
= add
, q
++; *s
&& *s
!= *q
; s
++);
4361 } else if (*q
== '<') {
4362 for (s
= add
; *s
&& !idigit(*s
); s
++);
4364 } else if (*q
== '[') {
4368 if ((not = (*x
== '!' || *x
== '^')))
4371 if (x
[1] == '-' && x
[2]) {
4372 char c1
= *x
, c2
= x
[2];
4374 for (s
= add
; *s
&& (*x
< c1
|| *x
> c2
); s
++);
4377 for (s
= add
; *s
&& *s
!= *x
; s
++);
4381 } else if (*q
!= '?' && *q
!= '*' && *q
!= '(' && *q
!= ')' &&
4382 *q
!= '|' && *q
!= '~' && *q
!= '#') {
4383 for (s
= add
; *s
&& *s
!= *q
; s
++);
4390 if (*matcher
&& !(add
= cfp_matcher_pats(matcher
, add
)))
4393 for (p
= pats
; *p
; p
++)
4395 *p
= dyncat(add
, *p
);
4400 cfp_bld_pats(UNUSED(int dirs
), LinkList names
, char *skipped
, char **pats
)
4402 LinkList ret
= newlinklist();
4404 int ol
, sl
= strlen(skipped
), pl
, dot
;
4407 dot
= (unset(GLOBDOTS
) && compprefix
&& *compprefix
== '.');
4408 for (node
= firstnode(names
); node
; incnode(node
)) {
4409 ol
= strlen(o
= (char *) getdata(node
));
4410 for (p
= pats
; *p
; p
++) {
4412 str
= (char *) zhalloc(ol
+ sl
+ pl
+ 1);
4414 strcpy(str
+ ol
, skipped
);
4415 strcpy(str
+ ol
+ sl
, *p
);
4416 addlinknode(ret
, str
);
4417 if (dot
&& **p
!= '.') {
4418 str
= (char *) zhalloc(ol
+ sl
+ pl
+ 2);
4420 strcpy(str
+ ol
, skipped
);
4422 strcpy(str
+ ol
+ sl
+ 1, *p
);
4423 addlinknode(ret
, str
);
4431 cfp_add_sdirs(LinkList final
, LinkList orig
, char *skipped
,
4432 char *sdirs
, char **fake
)
4436 if (*sdirs
&& (isset(GLOBDOTS
) || (compprefix
&& *compprefix
== '.'))) {
4437 if (!strcmp(sdirs
, "yes") || !strcmp(sdirs
, "true") ||
4438 !strcmp(sdirs
, "on") || !strcmp(sdirs
, "1"))
4440 else if (!strcmp(sdirs
, ".."))
4445 char *s1
= dyncat(skipped
, "..");
4446 char *s2
= (add
== 2 ? dyncat(skipped
, ".") : NULL
), *m
;
4448 for (node
= firstnode(orig
); node
; incnode(node
)) {
4449 if ((m
= (char *) getdata(node
))) {
4450 addlinknode(final
, dyncat(m
, s1
));
4452 addlinknode(final
, dyncat(m
, s2
));
4456 if (fake
&& *fake
) {
4458 char *m
, *f
, *p
, *t
, *a
, c
;
4459 int sl
= strlen(skipped
) + 1;
4460 struct stat st1
, st2
;
4463 for (; (f
= *fake
); fake
++) {
4465 for (p
= t
= f
; *p
; p
++) {
4468 else if (*p
== '\\' && p
[1] == ':') {
4470 * strip quoted colons here; rely
4471 * on tokenization to strip other backslashes
4483 pprog
= patcompile(f
, PAT_STATIC
, NULL
);
4485 for (node
= firstnode(orig
); node
; incnode(node
)) {
4486 if ((m
= (char *) getdata(node
)) &&
4487 ((pprog
? pattry(pprog
, m
) : !strcmp(f
, m
)) ||
4488 (!stat(f
, &st1
) && !stat((*m
? m
: "."), &st2
) &&
4489 st1
.st_dev
== st2
.st_dev
&&
4490 st1
.st_ino
== st2
.st_ino
))) {
4492 while (*p
&& inblank(*p
))
4496 for (f
= t
= p
; *p
; p
++) {
4499 else if (*p
== '\\' && p
[1])
4505 a
= (char *) zhalloc(strlen(m
) + sl
+ strlen(f
));
4509 addlinknode(final
, a
);
4521 cf_pats(int dirs
, int noopt
, LinkList names
, char **accept
, char *skipped
,
4522 char *matcher
, char *sdirs
, char **fake
, char **pats
)
4527 if ((ret
= cfp_test_exact(names
, accept
, skipped
)))
4528 return cfp_add_sdirs(ret
, names
, skipped
, sdirs
, fake
);
4536 cfp_opt_pats(pats
, matcher
);
4538 return cfp_add_sdirs(cfp_bld_pats(dirs
, names
, skipped
, pats
),
4539 names
, skipped
, sdirs
, fake
);
4543 cf_ignore(char **names
, LinkList ign
, char *style
, char *path
)
4545 int pl
= strlen(path
), tpar
, tpwd
, found
;
4546 struct stat nst
, est
, st
;
4549 tpar
= !!strstr(style
, "parent");
4550 if ((tpwd
= !!strstr(style
, "pwd")) && stat(pwd
, &est
))
4556 for (; (n
= *names
); names
++) {
4557 if (!ztat(n
, &nst
, 0) && S_ISDIR(nst
.st_mode
)) {
4558 if (tpwd
&& nst
.st_dev
== est
.st_dev
&& nst
.st_ino
== est
.st_ino
) {
4559 addlinknode(ign
, quotestring(n
, NULL
, QT_BACKSLASH
));
4562 if (tpar
&& !strncmp((c
= dupstring(n
)), path
, pl
)) {
4564 while ((e
= strrchr(c
, '/')) && e
> c
+ pl
) {
4566 if (!ztat(c
, &st
, 0) &&
4567 st
.st_dev
== nst
.st_dev
&& st
.st_ino
== nst
.st_ino
) {
4572 if (found
|| ((e
= strrchr(c
, '/')) && e
> c
+ pl
&&
4573 !ztat(c
, &st
, 0) && st
.st_dev
== nst
.st_dev
&&
4574 st
.st_ino
== nst
.st_ino
))
4575 addlinknode(ign
, quotestring(n
, NULL
, QT_BACKSLASH
));
4582 cf_remove_other(char **names
, char *pre
, int *amb
)
4586 if ((p
= strchr(pre
, '/'))) {
4590 pre
= dyncat(pre
, "/");
4593 for (n
= names
; *n
; n
++)
4594 if (strpfx(pre
, *n
))
4598 LinkList ret
= newlinklist();
4600 for (; *names
; names
++)
4601 if (strpfx(pre
, *names
))
4602 addlinknode(ret
, dupstring(*names
));
4608 if (!(p
= *names
++))
4613 if ((q
= strchr((p
= dupstring(p
)), '/')))
4618 for (; *names
; names
++)
4619 if (!strpfx(p
, *names
)) {
4626 if (!(p
= *names
++))
4629 for (; *names
; names
++)
4630 if (strcmp(p
, *names
)) {
4639 bin_compfiles(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
4641 if (incompfunc
!= 1) {
4642 zwarnnam(nam
, "can only be called from completion function");
4645 if (**args
!= '-') {
4646 zwarnnam(nam
, "missing option: %s", *args
);
4649 switch (args
[0][1]) {
4652 if (args
[0][2] && (args
[0][2] != '-' || args
[0][3])) {
4653 zwarnnam(nam
, "invalid option: %s", *args
);
4659 if (!args
[1] || !args
[2] || !args
[3] || !args
[4] || !args
[5] ||
4660 !args
[6] || (args
[0][1] == 'p' && !args
[7])) {
4661 zwarnnam(nam
, "too few arguments");
4665 if (!(tmp
= getaparam(args
[1]))) {
4666 zwarnnam(nam
, "unknown parameter: %s", args
[1]);
4669 for (l
= newlinklist(); *tmp
; tmp
++)
4670 addlinknode(l
, *tmp
);
4671 set_list_array(args
[1], cf_pats((args
[0][1] == 'P'), !!args
[0][2],
4672 l
, getaparam(args
[2]), args
[3],
4674 getaparam(args
[6]), args
+ 7));
4680 zwarnnam(nam
, "invalid option: %s", *args
);
4686 if (!args
[1] || !args
[2] || !args
[3] || !args
[4]) {
4687 zwarnnam(nam
, "too few arguments");
4691 zwarnnam(nam
, "too many arguments");
4695 tmp
= getaparam(args
[2]);
4699 addlinknode(l
, *tmp
);
4700 if (!(tmp
= getaparam(args
[1]))) {
4702 zwarnnam(nam
, "unknown parameter: %s", args
[1]);
4705 cf_ignore(tmp
, l
, args
[3], args
[4]);
4707 set_list_array(args
[2], l
);
4716 if (!args
[1] || !args
[2]) {
4717 zwarnnam(nam
, "too few arguments");
4721 zwarnnam(nam
, "too many arguments");
4725 if (!(tmp
= getaparam(args
[1]))) {
4727 zwarnnam(nam
, "unknown parameter: %s", args
[1]);
4730 if ((l
= cf_remove_other(tmp
, args
[2], &ret
)))
4731 set_list_array(args
[1], l
);
4736 zwarnnam(nam
, "invalid option: %s", *args
);
4741 bin_compgroups(char *nam
, char **args
, UNUSED(Options ops
), UNUSED(int func
))
4746 if (incompfunc
!= 1) {
4747 zwarnnam(nam
, "can only be called from completion function");
4750 SWITCHHEAPS(oldheap
, compheap
) {
4751 while ((n
= *args
++)) {
4753 begcmgroup(n
, CGF_NOSORT
|CGF_UNIQCON
);
4755 begcmgroup(n
, CGF_UNIQALL
);
4757 begcmgroup(n
, CGF_NOSORT
|CGF_UNIQCON
);
4759 begcmgroup(n
, CGF_UNIQALL
);
4761 begcmgroup(n
, CGF_NOSORT
);
4765 } SWITCHBACKHEAPS(oldheap
);
4770 static struct builtin bintab
[] = {
4771 BUILTIN("comparguments", 0, bin_comparguments
, 1, -1, 0, NULL
, NULL
),
4772 BUILTIN("compdescribe", 0, bin_compdescribe
, 3, -1, 0, NULL
, NULL
),
4773 BUILTIN("compfiles", 0, bin_compfiles
, 1, -1, 0, NULL
, NULL
),
4774 BUILTIN("compgroups", 0, bin_compgroups
, 1, -1, 0, NULL
, NULL
),
4775 BUILTIN("compquote", 0, bin_compquote
, 1, -1, 0, "p", NULL
),
4776 BUILTIN("comptags", 0, bin_comptags
, 1, -1, 0, NULL
, NULL
),
4777 BUILTIN("comptry", 0, bin_comptry
, 0, -1, 0, NULL
, NULL
),
4778 BUILTIN("compvalues", 0, bin_compvalues
, 1, -1, 0, NULL
, NULL
)
4781 static struct features module_features
= {
4782 bintab
, sizeof(bintab
)/sizeof(*bintab
),
4792 setup_(UNUSED(Module m
))
4794 memset(cadef_cache
, 0, sizeof(cadef_cache
));
4795 memset(cvdef_cache
, 0, sizeof(cvdef_cache
));
4797 memset(comptags
, 0, sizeof(comptags
));
4806 features_(Module m
, char ***features
)
4808 *features
= featuresarray(m
, &module_features
);
4814 enables_(Module m
, int **enables
)
4816 return handlefeatures(m
, &module_features
, enables
);
4830 return setfeatureenables(m
, &module_features
, NULL
);
4835 finish_(UNUSED(Module m
))
4839 for (i
= 0; i
< MAX_CACACHE
; i
++)
4840 freecadef(cadef_cache
[i
]);
4841 for (i
= 0; i
< MAX_CVCACHE
; i
++)
4842 freecvdef(cvdef_cache
[i
]);
4844 for (i
= 0; i
< MAX_TAGS
; i
++)
4845 freectags(comptags
[i
]);