]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/complete.def
Bash-4.1 patchlevel 11
[thirdparty/bash.git] / builtins / complete.def
CommitLineData
bb70624e 1This file is complete.def, from which is created complete.c.
3185942a 2It implements the builtins "complete", "compgen", and "compopt" in Bash.
bb70624e 3
3185942a 4Copyright (C) 1999-2009 Free Software Foundation, Inc.
bb70624e
JA
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
3185942a
JA
8Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
bb70624e 12
3185942a
JA
13Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
bb70624e 17
3185942a
JA
18You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
bb70624e
JA
20
21$PRODUCES complete.c
22
23$BUILTIN complete
24$DEPENDS_ON PROGRAMMABLE_COMPLETION
25$FUNCTION complete_builtin
0001803f 26$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
3185942a
JA
27Specify how arguments are to be completed by Readline.
28
29For each NAME, specify how arguments are to be completed. If no options
30are supplied, existing completion specifications are printed in a way that
31allows them to be reused as input.
32
33Options:
34 -p print existing completion specifications in a reusable format
35 -r remove a completion specification for each NAME, or, if no
36 NAMEs are supplied, all completion specifications
0001803f
CR
37 -D apply the completions and actions as the default for commands
38 without any specific completion defined
39 -E apply the completions and actions to "empty" commands --
40 completion attempted on a blank line
3185942a
JA
41
42When completion is attempted, the actions are applied in the order the
0001803f
CR
43uppercase-letter options are listed above. The -D option takes
44precedence over -E.
3185942a
JA
45
46Exit Status:
47Returns success unless an invalid option is supplied or an error occurs.
bb70624e
JA
48$END
49
50#include <config.h>
51
52#include <stdio.h>
53
54#include "../bashtypes.h"
55
56#if defined (HAVE_UNISTD_H)
57# include <unistd.h>
58#endif
59
60#include "../bashansi.h"
b80f6443 61#include "../bashintl.h"
bb70624e
JA
62
63#include "../shell.h"
64#include "../builtins.h"
65#include "../pcomplete.h"
b80f6443 66#include "../bashline.h"
bb70624e
JA
67
68#include "common.h"
69#include "bashgetopt.h"
70
f73dda09
JA
71#include <readline/readline.h>
72
bb70624e
JA
73#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
74
3185942a
JA
75/* Structure containing all the non-action (binary) options; filled in by
76 build_actions(). */
77struct _optflags {
78 int pflag;
79 int rflag;
0001803f 80 int Dflag;
3185942a
JA
81 int Eflag;
82};
83
f73dda09
JA
84static int find_compact __P((char *));
85static int find_compopt __P((char *));
86
3185942a 87static int build_actions __P((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
f73dda09
JA
88
89static int remove_cmd_completions __P((WORD_LIST *));
bb70624e 90
7117c2d2
JA
91static int print_one_completion __P((char *, COMPSPEC *));
92static int print_compitem __P((BUCKET_CONTENTS *));
3185942a 93static void print_compopts __P((const char *, COMPSPEC *, int));
f73dda09
JA
94static void print_all_completions __P((void));
95static int print_cmd_completions __P((WORD_LIST *));
bb70624e 96
7117c2d2 97static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
bb70624e 98
3185942a
JA
99static const struct _compacts {
100 const char * const actname;
bb70624e
JA
101 int actflag;
102 int actopt;
103} compacts[] = {
104 { "alias", CA_ALIAS, 'a' },
105 { "arrayvar", CA_ARRAYVAR, 0 },
106 { "binding", CA_BINDING, 0 },
107 { "builtin", CA_BUILTIN, 'b' },
108 { "command", CA_COMMAND, 'c' },
109 { "directory", CA_DIRECTORY, 'd' },
110 { "disabled", CA_DISABLED, 0 },
111 { "enabled", CA_ENABLED, 0 },
112 { "export", CA_EXPORT, 'e' },
113 { "file", CA_FILE, 'f' },
114 { "function", CA_FUNCTION, 0 },
115 { "helptopic", CA_BUILTIN, 0 }, /* for now */
116 { "hostname", CA_HOSTNAME, 0 },
f73dda09 117 { "group", CA_GROUP, 'g' },
bb70624e
JA
118 { "job", CA_JOB, 'j' },
119 { "keyword", CA_KEYWORD, 'k' },
120 { "running", CA_RUNNING, 0 },
7117c2d2 121 { "service", CA_SERVICE, 's' },
bb70624e
JA
122 { "setopt", CA_SETOPT, 0 },
123 { "shopt", CA_SHOPT, 0 },
124 { "signal", CA_SIGNAL, 0 },
125 { "stopped", CA_STOPPED, 0 },
126 { "user", CA_USER, 'u' },
127 { "variable", CA_VARIABLE, 'v' },
128 { (char *)NULL, 0, 0 },
129};
130
7117c2d2 131/* This should be a STRING_INT_ALIST */
3185942a
JA
132const static struct _compopt {
133 const char * const optname;
28ef6c31
JA
134 int optflag;
135} compopts[] = {
b80f6443 136 { "bashdefault", COPT_BASHDEFAULT },
28ef6c31
JA
137 { "default", COPT_DEFAULT },
138 { "dirnames", COPT_DIRNAMES },
139 { "filenames",COPT_FILENAMES},
7117c2d2 140 { "nospace", COPT_NOSPACE },
b80f6443 141 { "plusdirs", COPT_PLUSDIRS },
28ef6c31
JA
142 { (char *)NULL, 0 },
143};
144
bb70624e
JA
145static int
146find_compact (name)
147 char *name;
148{
149 register int i;
150
151 for (i = 0; compacts[i].actname; i++)
152 if (STREQ (name, compacts[i].actname))
153 return i;
154 return -1;
155}
156
28ef6c31
JA
157static int
158find_compopt (name)
159 char *name;
160{
161 register int i;
162
163 for (i = 0; compopts[i].optname; i++)
164 if (STREQ (name, compopts[i].optname))
165 return i;
166 return -1;
167}
168
169/* Build the actions and compspec options from the options specified in LIST.
170 ACTP is a pointer to an unsigned long in which to place the bitmap of
171 actions. OPTP is a pointer to an unsigned long in which to place the
172 btmap of compspec options (arguments to `-o'). PP, if non-null, gets 1
173 if -p is supplied; RP, if non-null, gets 1 if -r is supplied.
174 If either is null, the corresponding option generates an error.
175 This also sets variables corresponding to options that take arguments as
176 a side effect; the caller should ensure that those variables are set to
177 NULL before calling build_actions. Return value:
bb70624e
JA
178 EX_USAGE = bad option
179 EXECUTION_SUCCESS = some options supplied
180 EXECUTION_FAILURE = no options supplied
181*/
182
183static int
3185942a 184build_actions (list, flagp, actp, optp)
bb70624e 185 WORD_LIST *list;
3185942a 186 struct _optflags *flagp;
28ef6c31 187 unsigned long *actp, *optp;
bb70624e 188{
f73dda09 189 int opt, ind, opt_given;
28ef6c31 190 unsigned long acts, copts;
bb70624e 191
28ef6c31 192 acts = copts = (unsigned long)0L;
bb70624e
JA
193 opt_given = 0;
194
195 reset_internal_getopt ();
0001803f 196 while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DE")) != -1)
bb70624e
JA
197 {
198 opt_given = 1;
199 switch (opt)
200 {
201 case 'r':
3185942a 202 if (flagp)
bb70624e 203 {
3185942a 204 flagp->rflag = 1;
bb70624e
JA
205 break;
206 }
207 else
208 {
7117c2d2 209 sh_invalidopt ("-r");
bb70624e
JA
210 builtin_usage ();
211 return (EX_USAGE);
212 }
213
214 case 'p':
3185942a 215 if (flagp)
bb70624e 216 {
3185942a 217 flagp->pflag = 1;
bb70624e
JA
218 break;
219 }
220 else
221 {
7117c2d2 222 sh_invalidopt ("-p");
bb70624e
JA
223 builtin_usage ();
224 return (EX_USAGE);
225 }
226
227 case 'a':
228 acts |= CA_ALIAS;
229 break;
230 case 'b':
231 acts |= CA_BUILTIN;
232 break;
233 case 'c':
234 acts |= CA_COMMAND;
235 break;
236 case 'd':
237 acts |= CA_DIRECTORY;
238 break;
239 case 'e':
240 acts |= CA_EXPORT;
241 break;
242 case 'f':
243 acts |= CA_FILE;
244 break;
f73dda09
JA
245 case 'g':
246 acts |= CA_GROUP;
247 break;
bb70624e
JA
248 case 'j':
249 acts |= CA_JOB;
250 break;
251 case 'k':
252 acts |= CA_KEYWORD;
253 break;
7117c2d2
JA
254 case 's':
255 acts |= CA_SERVICE;
256 break;
bb70624e
JA
257 case 'u':
258 acts |= CA_USER;
259 break;
260 case 'v':
261 acts |= CA_VARIABLE;
262 break;
28ef6c31
JA
263 case 'o':
264 ind = find_compopt (list_optarg);
265 if (ind < 0)
266 {
7117c2d2 267 sh_invalidoptname (list_optarg);
28ef6c31
JA
268 return (EX_USAGE);
269 }
270 copts |= compopts[ind].optflag;
271 break;
bb70624e
JA
272 case 'A':
273 ind = find_compact (list_optarg);
274 if (ind < 0)
275 {
b80f6443 276 builtin_error (_("%s: invalid action name"), list_optarg);
bb70624e
JA
277 return (EX_USAGE);
278 }
279 acts |= compacts[ind].actflag;
280 break;
281 case 'C':
282 Carg = list_optarg;
283 break;
0001803f
CR
284 case 'D':
285 if (flagp)
286 {
287 flagp->Dflag = 1;
288 break;
289 }
290 else
291 {
292 sh_invalidopt ("-D");
293 builtin_usage ();
294 return (EX_USAGE);
295 }
3185942a
JA
296 case 'E':
297 if (flagp)
298 {
299 flagp->Eflag = 1;
300 break;
301 }
302 else
303 {
304 sh_invalidopt ("-E");
305 builtin_usage ();
306 return (EX_USAGE);
307 }
bb70624e
JA
308 case 'F':
309 Farg = list_optarg;
310 break;
311 case 'G':
312 Garg = list_optarg;
313 break;
314 case 'P':
315 Parg = list_optarg;
316 break;
317 case 'S':
318 Sarg = list_optarg;
319 break;
320 case 'W':
321 Warg = list_optarg;
322 break;
323 case 'X':
324 Xarg = list_optarg;
325 break;
326 default:
327 builtin_usage ();
328 return (EX_USAGE);
329 }
330 }
331
332 *actp = acts;
28ef6c31
JA
333 *optp = copts;
334
bb70624e
JA
335 return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
336}
337
338/* Add, remove, and display completion specifiers. */
339int
340complete_builtin (list)
341 WORD_LIST *list;
342{
3185942a 343 int opt_given, rval;
28ef6c31 344 unsigned long acts, copts;
bb70624e 345 COMPSPEC *cs;
3185942a
JA
346 struct _optflags oflags;
347 WORD_LIST *l, *wl;
bb70624e
JA
348
349 if (list == 0)
350 {
351 print_all_completions ();
352 return (EXECUTION_SUCCESS);
353 }
354
0001803f 355 opt_given = oflags.pflag = oflags.rflag = oflags.Dflag = oflags.Eflag = 0;
3185942a 356
28ef6c31 357 acts = copts = (unsigned long)0L;
7117c2d2 358 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
bb70624e
JA
359 cs = (COMPSPEC *)NULL;
360
361 /* Build the actions from the arguments. Also sets the [A-Z]arg variables
362 as a side effect if they are supplied as options. */
3185942a 363 rval = build_actions (list, &oflags, &acts, &copts);
bb70624e
JA
364 if (rval == EX_USAGE)
365 return (rval);
366 opt_given = rval != EXECUTION_FAILURE;
367
368 list = loptend;
369
0001803f
CR
370 wl = oflags.Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL)
371 : (oflags.Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0);
3185942a 372
bb70624e 373 /* -p overrides everything else */
3185942a 374 if (oflags.pflag || (list == 0 && opt_given == 0))
bb70624e 375 {
3185942a
JA
376 if (wl)
377 {
378 rval = print_cmd_completions (wl);
379 dispose_words (wl);
380 return rval;
381 }
382 else if (list == 0)
bb70624e
JA
383 {
384 print_all_completions ();
385 return (EXECUTION_SUCCESS);
386 }
387 return (print_cmd_completions (list));
388 }
389
390 /* next, -r overrides everything else. */
3185942a 391 if (oflags.rflag)
bb70624e 392 {
3185942a
JA
393 if (wl)
394 {
395 rval = remove_cmd_completions (wl);
396 dispose_words (wl);
397 return rval;
398 }
399 else if (list == 0)
bb70624e 400 {
7117c2d2 401 progcomp_flush ();
bb70624e
JA
402 return (EXECUTION_SUCCESS);
403 }
404 return (remove_cmd_completions (list));
405 }
406
3185942a 407 if (wl == 0 && list == 0 && opt_given)
bb70624e
JA
408 {
409 builtin_usage ();
410 return (EX_USAGE);
411 }
412
413 /* If we get here, we need to build a compspec and add it for each
414 remaining argument. */
7117c2d2 415 cs = compspec_create ();
bb70624e 416 cs->actions = acts;
28ef6c31 417 cs->options = copts;
bb70624e
JA
418
419 cs->globpat = STRDUP (Garg);
420 cs->words = STRDUP (Warg);
421 cs->prefix = STRDUP (Parg);
422 cs->suffix = STRDUP (Sarg);
423 cs->funcname = STRDUP (Farg);
424 cs->command = STRDUP (Carg);
425 cs->filterpat = STRDUP (Xarg);
426
3185942a 427 for (rval = EXECUTION_SUCCESS, l = wl ? wl : list ; l; l = l->next)
bb70624e
JA
428 {
429 /* Add CS as the compspec for the specified commands. */
3185942a 430 if (progcomp_insert (l->word->word, cs) == 0)
28ef6c31 431 rval = EXECUTION_FAILURE;
bb70624e
JA
432 }
433
3185942a 434 dispose_words (wl);
bb70624e
JA
435 return (rval);
436}
437
438static int
439remove_cmd_completions (list)
440 WORD_LIST *list;
441{
442 WORD_LIST *l;
443 int ret;
444
445 for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
446 {
7117c2d2 447 if (progcomp_remove (l->word->word) == 0)
bb70624e 448 {
b80f6443 449 builtin_error (_("%s: no completion specification"), l->word->word);
bb70624e
JA
450 ret = EXECUTION_FAILURE;
451 }
452 }
453 return ret;
454}
455
456#define SQPRINTARG(a, f) \
457 do { \
458 if (a) \
459 { \
28ef6c31 460 x = sh_single_quote (a); \
bb70624e
JA
461 printf ("%s %s ", f, x); \
462 free (x); \
463 } \
464 } while (0)
465
466#define PRINTARG(a, f) \
467 do { \
468 if (a) \
469 printf ("%s %s ", f, a); \
470 } while (0)
471
472#define PRINTOPT(a, f) \
473 do { \
474 if (acts & a) \
475 printf ("%s ", f); \
476 } while (0)
477
478#define PRINTACT(a, f) \
479 do { \
480 if (acts & a) \
481 printf ("-A %s ", f); \
482 } while (0)
483
28ef6c31
JA
484#define PRINTCOMPOPT(a, f) \
485 do { \
486 if (copts & a) \
487 printf ("-o %s ", f); \
488 } while (0)
489
3185942a
JA
490#define XPRINTCOMPOPT(a, f) \
491 do { \
492 if (copts & a) \
493 printf ("-o %s ", f); \
494 else \
495 printf ("+o %s ", f); \
496 } while (0)
497
7117c2d2 498static int
bb70624e
JA
499print_one_completion (cmd, cs)
500 char *cmd;
501 COMPSPEC *cs;
502{
28ef6c31 503 unsigned long acts, copts;
bb70624e
JA
504 char *x;
505
506 printf ("complete ");
507
28ef6c31
JA
508 copts = cs->options;
509
510 /* First, print the -o options. */
b80f6443 511 PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
28ef6c31
JA
512 PRINTCOMPOPT (COPT_DEFAULT, "default");
513 PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
514 PRINTCOMPOPT (COPT_FILENAMES, "filenames");
7117c2d2 515 PRINTCOMPOPT (COPT_NOSPACE, "nospace");
b80f6443 516 PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
28ef6c31 517
bb70624e
JA
518 acts = cs->actions;
519
28ef6c31 520 /* simple flags next */
bb70624e
JA
521 PRINTOPT (CA_ALIAS, "-a");
522 PRINTOPT (CA_BUILTIN, "-b");
523 PRINTOPT (CA_COMMAND, "-c");
524 PRINTOPT (CA_DIRECTORY, "-d");
525 PRINTOPT (CA_EXPORT, "-e");
526 PRINTOPT (CA_FILE, "-f");
f73dda09 527 PRINTOPT (CA_GROUP, "-g");
bb70624e 528 PRINTOPT (CA_JOB, "-j");
7117c2d2
JA
529 PRINTOPT (CA_KEYWORD, "-k");
530 PRINTOPT (CA_SERVICE, "-s");
bb70624e
JA
531 PRINTOPT (CA_USER, "-u");
532 PRINTOPT (CA_VARIABLE, "-v");
533
534 /* now the rest of the actions */
535 PRINTACT (CA_ARRAYVAR, "arrayvar");
536 PRINTACT (CA_BINDING, "binding");
537 PRINTACT (CA_DISABLED, "disabled");
538 PRINTACT (CA_ENABLED, "enabled");
539 PRINTACT (CA_FUNCTION, "function");
540 PRINTACT (CA_HELPTOPIC, "helptopic");
541 PRINTACT (CA_HOSTNAME, "hostname");
542 PRINTACT (CA_RUNNING, "running");
543 PRINTACT (CA_SETOPT, "setopt");
544 PRINTACT (CA_SHOPT, "shopt");
545 PRINTACT (CA_SIGNAL, "signal");
546 PRINTACT (CA_STOPPED, "stopped");
547
548 /* now the rest of the arguments */
549
550 /* arguments that require quoting */
551 SQPRINTARG (cs->globpat, "-G");
552 SQPRINTARG (cs->words, "-W");
553 SQPRINTARG (cs->prefix, "-P");
554 SQPRINTARG (cs->suffix, "-S");
555 SQPRINTARG (cs->filterpat, "-X");
556
3185942a
JA
557 SQPRINTARG (cs->command, "-C");
558
bb70624e
JA
559 /* simple arguments that don't require quoting */
560 PRINTARG (cs->funcname, "-F");
bb70624e 561
0001803f
CR
562 if (STREQ (cmd, EMPTYCMD))
563 printf ("-E\n");
564 else if (STREQ (cmd, DEFAULTCMD))
565 printf ("-D\n");
566 else
567 printf ("%s\n", cmd);
7117c2d2
JA
568
569 return (0);
570}
571
3185942a
JA
572static void
573print_compopts (cmd, cs, full)
574 const char *cmd;
575 COMPSPEC *cs;
576 int full;
577{
578 int copts;
579
580 printf ("compopt ");
581 copts = cs->options;
582
583 if (full)
584 {
585 XPRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
586 XPRINTCOMPOPT (COPT_DEFAULT, "default");
587 XPRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
588 XPRINTCOMPOPT (COPT_FILENAMES, "filenames");
589 XPRINTCOMPOPT (COPT_NOSPACE, "nospace");
590 XPRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
591 }
592 else
593 {
594 PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
595 PRINTCOMPOPT (COPT_DEFAULT, "default");
596 PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
597 PRINTCOMPOPT (COPT_FILENAMES, "filenames");
598 PRINTCOMPOPT (COPT_NOSPACE, "nospace");
599 PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
600 }
601
0001803f
CR
602 if (STREQ (cmd, EMPTYCMD))
603 printf ("-E\n");
604 else if (STREQ (cmd, DEFAULTCMD))
605 printf ("-D\n");
606 else
607 printf ("%s\n", cmd);
3185942a
JA
608}
609
7117c2d2
JA
610static int
611print_compitem (item)
612 BUCKET_CONTENTS *item;
613{
614 COMPSPEC *cs;
615 char *cmd;
616
617 cmd = item->key;
618 cs = (COMPSPEC *)item->data;
619
620 return (print_one_completion (cmd, cs));
bb70624e
JA
621}
622
623static void
624print_all_completions ()
625{
7117c2d2 626 progcomp_walk (print_compitem);
bb70624e
JA
627}
628
629static int
630print_cmd_completions (list)
631 WORD_LIST *list;
632{
633 WORD_LIST *l;
634 COMPSPEC *cs;
635 int ret;
636
637 for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
638 {
7117c2d2 639 cs = progcomp_search (l->word->word);
bb70624e 640 if (cs)
28ef6c31 641 print_one_completion (l->word->word, cs);
bb70624e
JA
642 else
643 {
b80f6443 644 builtin_error (_("%s: no completion specification"), l->word->word);
bb70624e
JA
645 ret = EXECUTION_FAILURE;
646 }
647 }
3185942a
JA
648
649 return (sh_chkwrite (ret));
bb70624e
JA
650}
651
652$BUILTIN compgen
653$DEPENDS_ON PROGRAMMABLE_COMPLETION
654$FUNCTION compgen_builtin
3185942a
JA
655$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
656Display possible completions depending on the options.
657
658Intended to be used from within a shell function generating possible
659completions. If the optional WORD argument is supplied, matches against
660WORD are generated.
661
662Exit Status:
663Returns success unless an invalid option is supplied or an error occurs.
bb70624e
JA
664$END
665
666int
667compgen_builtin (list)
668 WORD_LIST *list;
669{
670 int rval;
28ef6c31 671 unsigned long acts, copts;
bb70624e
JA
672 COMPSPEC *cs;
673 STRINGLIST *sl;
b80f6443 674 char *word, **matches;
bb70624e
JA
675
676 if (list == 0)
677 return (EXECUTION_SUCCESS);
678
28ef6c31 679 acts = copts = (unsigned long)0L;
7117c2d2 680 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
bb70624e
JA
681 cs = (COMPSPEC *)NULL;
682
683 /* Build the actions from the arguments. Also sets the [A-Z]arg variables
684 as a side effect if they are supplied as options. */
3185942a 685 rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts);
bb70624e
JA
686 if (rval == EX_USAGE)
687 return (rval);
688 if (rval == EXECUTION_FAILURE)
689 return (EXECUTION_SUCCESS);
690
691 list = loptend;
692
693 word = (list && list->word) ? list->word->word : "";
694
695 if (Farg)
b80f6443 696 builtin_error (_("warning: -F option may not work as you expect"));
bb70624e 697 if (Carg)
b80f6443 698 builtin_error (_("warning: -C option may not work as you expect"));
bb70624e
JA
699
700 /* If we get here, we need to build a compspec and evaluate it. */
7117c2d2 701 cs = compspec_create ();
bb70624e 702 cs->actions = acts;
28ef6c31 703 cs->options = copts;
bb70624e
JA
704 cs->refcount = 1;
705
706 cs->globpat = STRDUP (Garg);
707 cs->words = STRDUP (Warg);
708 cs->prefix = STRDUP (Parg);
709 cs->suffix = STRDUP (Sarg);
710 cs->funcname = STRDUP (Farg);
711 cs->command = STRDUP (Carg);
712 cs->filterpat = STRDUP (Xarg);
713
714 rval = EXECUTION_FAILURE;
0001803f 715 sl = gen_compspec_completions (cs, "compgen", word, 0, 0, 0);
f73dda09 716
b80f6443
JA
717 /* If the compspec wants the bash default completions, temporarily
718 turn off programmable completion and call the bash completion code. */
719 if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT))
720 {
721 matches = bash_default_completion (word, 0, 0, 0, 0);
722 sl = completions_to_stringlist (matches);
723 strvec_dispose (matches);
724 }
725
f73dda09
JA
726 /* This isn't perfect, but it's the best we can do, given what readline
727 exports from its set of completion utility functions. */
728 if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
729 {
f73dda09
JA
730 matches = rl_completion_matches (word, rl_filename_completion_function);
731 sl = completions_to_stringlist (matches);
7117c2d2 732 strvec_dispose (matches);
f73dda09
JA
733 }
734
bb70624e
JA
735 if (sl)
736 {
f73dda09 737 if (sl->list && sl->list_len)
bb70624e
JA
738 {
739 rval = EXECUTION_SUCCESS;
7117c2d2 740 strlist_print (sl, (char *)NULL);
bb70624e 741 }
7117c2d2 742 strlist_dispose (sl);
bb70624e
JA
743 }
744
7117c2d2 745 compspec_dispose (cs);
bb70624e
JA
746 return (rval);
747}
3185942a
JA
748
749$BUILTIN compopt
750$DEPENDS_ON PROGRAMMABLE_COMPLETION
751$FUNCTION compopt_builtin
0001803f 752$SHORT_DOC compopt [-o|+o option] [-DE] [name ...]
3185942a
JA
753Modify or display completion options.
754
755Modify the completion options for each NAME, or, if no NAMEs are supplied,
756the completion currently begin executed. If no OPTIONs are givenm, print
757the completion options for each NAME or the current completion specification.
758
759Options:
760 -o option Set completion option OPTION for each NAME
0001803f
CR
761 -D Change options for the "default" command completion
762 -E Change options for the "empty" command completion
3185942a
JA
763
764Using `+o' instead of `-o' turns off the specified option.
765
766Arguments:
767
768Each NAME refers to a command for which a completion specification must
769have previously been defined using the `complete' builtin. If no NAMEs
770are supplied, compopt must be called by a function currently generating
771completions, and the options for that currently-executing completion
772generator are modified.
773
774Exit Status:
775Returns success unless an invalid option is supplied or NAME does not
776have a completion specification defined.
777$END
778
779int
780compopt_builtin (list)
781 WORD_LIST *list;
782{
0001803f
CR
783 int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag;
784 WORD_LIST *l, *wl;
3185942a
JA
785 COMPSPEC *cs;
786
0001803f 787 opts_on = opts_off = Eflag = Dflag = 0;
3185942a
JA
788 ret = EXECUTION_SUCCESS;
789
790 reset_internal_getopt ();
0001803f 791 while ((opt = internal_getopt (list, "+o:DE")) != EOF)
3185942a
JA
792 {
793 opts = (list_opttype == '-') ? &opts_on : &opts_off;
794
795 switch (opt)
796 {
797 case 'o':
798 oind = find_compopt (list_optarg);
799 if (oind < 0)
800 {
801 sh_invalidoptname (list_optarg);
802 return (EX_USAGE);
803 }
804 *opts |= compopts[oind].optflag;
805 break;
0001803f
CR
806 case 'D':
807 Dflag = 1;
808 break;
809 case 'E':
810 Eflag = 1;
811 break;
3185942a
JA
812 default:
813 builtin_usage ();
814 return (EX_USAGE);
815 }
816 }
817 list = loptend;
818
0001803f
CR
819 wl = Dflag ? make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL)
820 : (Eflag ? make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL) : 0);
821
822 if (list == 0 && wl == 0)
3185942a
JA
823 {
824 if (RL_ISSTATE (RL_STATE_COMPLETING) == 0 || pcomp_curcs == 0)
825 {
826 builtin_error (_("not currently executing completion function"));
827 return (EXECUTION_FAILURE);
828 }
829 cs = pcomp_curcs;
830
831 if (opts_on == 0 && opts_off == 0)
832 {
833 print_compopts (pcomp_curcmd, cs, 1);
834 return (sh_chkwrite (ret));
835 }
836
837 /* Set the compspec options */
838 pcomp_set_compspec_options (cs, opts_on, 1);
839 pcomp_set_compspec_options (cs, opts_off, 0);
840
841 /* And change the readline variables the options control */
842 pcomp_set_readline_variables (opts_on, 1);
843 pcomp_set_readline_variables (opts_off, 0);
844
845 return (ret);
846 }
847
0001803f 848 for (l = wl ? wl : list; l; l = l->next)
3185942a
JA
849 {
850 cs = progcomp_search (l->word->word);
851 if (cs == 0)
852 {
853 builtin_error (_("%s: no completion specification"), l->word->word);
854 ret = EXECUTION_FAILURE;
855 continue;
856 }
857 if (opts_on == 0 && opts_off == 0)
858 {
859 print_compopts (l->word->word, cs, 1);
860 continue; /* XXX -- fill in later */
861 }
862
863 /* Set the compspec options */
864 pcomp_set_compspec_options (cs, opts_on, 1);
865 pcomp_set_compspec_options (cs, opts_off, 0);
866 }
867
868 return (ret);
869}