]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/complete.def
Bash-4.2 patch 24
[thirdparty/bash.git] / builtins / complete.def
1 This file is complete.def, from which is created complete.c.
2 It implements the builtins "complete", "compgen", and "compopt" in Bash.
3
4 Copyright (C) 1999-2010 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20
21 $PRODUCES complete.c
22
23 $BUILTIN complete
24 $DEPENDS_ON PROGRAMMABLE_COMPLETION
25 $FUNCTION complete_builtin
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 ...]
27 Specify how arguments are to be completed by Readline.
28
29 For each NAME, specify how arguments are to be completed. If no options
30 are supplied, existing completion specifications are printed in a way that
31 allows them to be reused as input.
32
33 Options:
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
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
41
42 When completion is attempted, the actions are applied in the order the
43 uppercase-letter options are listed above. The -D option takes
44 precedence over -E.
45
46 Exit Status:
47 Returns success unless an invalid option is supplied or an error occurs.
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"
61 #include "../bashintl.h"
62
63 #include "../shell.h"
64 #include "../builtins.h"
65 #include "../pcomplete.h"
66 #include "../bashline.h"
67
68 #include "common.h"
69 #include "bashgetopt.h"
70
71 #include <readline/readline.h>
72
73 #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
74
75 /* Structure containing all the non-action (binary) options; filled in by
76 build_actions(). */
77 struct _optflags {
78 int pflag;
79 int rflag;
80 int Dflag;
81 int Eflag;
82 };
83
84 static int find_compact __P((char *));
85 static int find_compopt __P((char *));
86
87 static int build_actions __P((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *));
88
89 static int remove_cmd_completions __P((WORD_LIST *));
90
91 static int print_one_completion __P((char *, COMPSPEC *));
92 static int print_compitem __P((BUCKET_CONTENTS *));
93 static void print_compopts __P((const char *, COMPSPEC *, int));
94 static void print_all_completions __P((void));
95 static int print_cmd_completions __P((WORD_LIST *));
96
97 static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
98
99 static const struct _compacts {
100 const char * const actname;
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 },
117 { "group", CA_GROUP, 'g' },
118 { "job", CA_JOB, 'j' },
119 { "keyword", CA_KEYWORD, 'k' },
120 { "running", CA_RUNNING, 0 },
121 { "service", CA_SERVICE, 's' },
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
131 /* This should be a STRING_INT_ALIST */
132 const static struct _compopt {
133 const char * const optname;
134 int optflag;
135 } compopts[] = {
136 { "bashdefault", COPT_BASHDEFAULT },
137 { "default", COPT_DEFAULT },
138 { "dirnames", COPT_DIRNAMES },
139 { "filenames",COPT_FILENAMES},
140 { "nospace", COPT_NOSPACE },
141 { "plusdirs", COPT_PLUSDIRS },
142 { (char *)NULL, 0 },
143 };
144
145 static int
146 find_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
157 static int
158 find_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:
178 EX_USAGE = bad option
179 EXECUTION_SUCCESS = some options supplied
180 EXECUTION_FAILURE = no options supplied
181 */
182
183 static int
184 build_actions (list, flagp, actp, optp)
185 WORD_LIST *list;
186 struct _optflags *flagp;
187 unsigned long *actp, *optp;
188 {
189 int opt, ind, opt_given;
190 unsigned long acts, copts;
191
192 acts = copts = (unsigned long)0L;
193 opt_given = 0;
194
195 reset_internal_getopt ();
196 while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DE")) != -1)
197 {
198 opt_given = 1;
199 switch (opt)
200 {
201 case 'r':
202 if (flagp)
203 {
204 flagp->rflag = 1;
205 break;
206 }
207 else
208 {
209 sh_invalidopt ("-r");
210 builtin_usage ();
211 return (EX_USAGE);
212 }
213
214 case 'p':
215 if (flagp)
216 {
217 flagp->pflag = 1;
218 break;
219 }
220 else
221 {
222 sh_invalidopt ("-p");
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;
245 case 'g':
246 acts |= CA_GROUP;
247 break;
248 case 'j':
249 acts |= CA_JOB;
250 break;
251 case 'k':
252 acts |= CA_KEYWORD;
253 break;
254 case 's':
255 acts |= CA_SERVICE;
256 break;
257 case 'u':
258 acts |= CA_USER;
259 break;
260 case 'v':
261 acts |= CA_VARIABLE;
262 break;
263 case 'o':
264 ind = find_compopt (list_optarg);
265 if (ind < 0)
266 {
267 sh_invalidoptname (list_optarg);
268 return (EX_USAGE);
269 }
270 copts |= compopts[ind].optflag;
271 break;
272 case 'A':
273 ind = find_compact (list_optarg);
274 if (ind < 0)
275 {
276 builtin_error (_("%s: invalid action name"), list_optarg);
277 return (EX_USAGE);
278 }
279 acts |= compacts[ind].actflag;
280 break;
281 case 'C':
282 Carg = list_optarg;
283 break;
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 }
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 }
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;
333 *optp = copts;
334
335 return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
336 }
337
338 /* Add, remove, and display completion specifiers. */
339 int
340 complete_builtin (list)
341 WORD_LIST *list;
342 {
343 int opt_given, rval;
344 unsigned long acts, copts;
345 COMPSPEC *cs;
346 struct _optflags oflags;
347 WORD_LIST *l, *wl;
348
349 if (list == 0)
350 {
351 print_all_completions ();
352 return (EXECUTION_SUCCESS);
353 }
354
355 opt_given = oflags.pflag = oflags.rflag = oflags.Dflag = oflags.Eflag = 0;
356
357 acts = copts = (unsigned long)0L;
358 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
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. */
363 rval = build_actions (list, &oflags, &acts, &copts);
364 if (rval == EX_USAGE)
365 return (rval);
366 opt_given = rval != EXECUTION_FAILURE;
367
368 list = loptend;
369
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);
372
373 /* -p overrides everything else */
374 if (oflags.pflag || (list == 0 && opt_given == 0))
375 {
376 if (wl)
377 {
378 rval = print_cmd_completions (wl);
379 dispose_words (wl);
380 return rval;
381 }
382 else if (list == 0)
383 {
384 print_all_completions ();
385 return (EXECUTION_SUCCESS);
386 }
387 return (print_cmd_completions (list));
388 }
389
390 /* next, -r overrides everything else. */
391 if (oflags.rflag)
392 {
393 if (wl)
394 {
395 rval = remove_cmd_completions (wl);
396 dispose_words (wl);
397 return rval;
398 }
399 else if (list == 0)
400 {
401 progcomp_flush ();
402 return (EXECUTION_SUCCESS);
403 }
404 return (remove_cmd_completions (list));
405 }
406
407 if (wl == 0 && list == 0 && opt_given)
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. */
415 cs = compspec_create ();
416 cs->actions = acts;
417 cs->options = copts;
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
427 for (rval = EXECUTION_SUCCESS, l = wl ? wl : list ; l; l = l->next)
428 {
429 /* Add CS as the compspec for the specified commands. */
430 if (progcomp_insert (l->word->word, cs) == 0)
431 rval = EXECUTION_FAILURE;
432 }
433
434 dispose_words (wl);
435 return (rval);
436 }
437
438 static int
439 remove_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 {
447 if (progcomp_remove (l->word->word) == 0)
448 {
449 builtin_error (_("%s: no completion specification"), l->word->word);
450 ret = EXECUTION_FAILURE;
451 }
452 }
453 return ret;
454 }
455
456 #define SQPRINTARG(a, f) \
457 do { \
458 if (a) \
459 { \
460 x = sh_single_quote (a); \
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
484 #define PRINTCOMPOPT(a, f) \
485 do { \
486 if (copts & a) \
487 printf ("-o %s ", f); \
488 } while (0)
489
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
498 static int
499 print_one_completion (cmd, cs)
500 char *cmd;
501 COMPSPEC *cs;
502 {
503 unsigned long acts, copts;
504 char *x;
505
506 printf ("complete ");
507
508 copts = cs->options;
509
510 /* First, print the -o options. */
511 PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
512 PRINTCOMPOPT (COPT_DEFAULT, "default");
513 PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
514 PRINTCOMPOPT (COPT_FILENAMES, "filenames");
515 PRINTCOMPOPT (COPT_NOSPACE, "nospace");
516 PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
517
518 acts = cs->actions;
519
520 /* simple flags next */
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");
527 PRINTOPT (CA_GROUP, "-g");
528 PRINTOPT (CA_JOB, "-j");
529 PRINTOPT (CA_KEYWORD, "-k");
530 PRINTOPT (CA_SERVICE, "-s");
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
557 SQPRINTARG (cs->command, "-C");
558
559 /* simple arguments that don't require quoting */
560 PRINTARG (cs->funcname, "-F");
561
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);
568
569 return (0);
570 }
571
572 static void
573 print_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
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);
608 }
609
610 static int
611 print_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));
621 }
622
623 static void
624 print_all_completions ()
625 {
626 progcomp_walk (print_compitem);
627 }
628
629 static int
630 print_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 {
639 cs = progcomp_search (l->word->word);
640 if (cs)
641 print_one_completion (l->word->word, cs);
642 else
643 {
644 builtin_error (_("%s: no completion specification"), l->word->word);
645 ret = EXECUTION_FAILURE;
646 }
647 }
648
649 return (sh_chkwrite (ret));
650 }
651
652 $BUILTIN compgen
653 $DEPENDS_ON PROGRAMMABLE_COMPLETION
654 $FUNCTION compgen_builtin
655 $SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
656 Display possible completions depending on the options.
657
658 Intended to be used from within a shell function generating possible
659 completions. If the optional WORD argument is supplied, matches against
660 WORD are generated.
661
662 Exit Status:
663 Returns success unless an invalid option is supplied or an error occurs.
664 $END
665
666 int
667 compgen_builtin (list)
668 WORD_LIST *list;
669 {
670 int rval;
671 unsigned long acts, copts;
672 COMPSPEC *cs;
673 STRINGLIST *sl;
674 char *word, **matches;
675
676 if (list == 0)
677 return (EXECUTION_SUCCESS);
678
679 acts = copts = (unsigned long)0L;
680 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
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. */
685 rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts);
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)
696 builtin_error (_("warning: -F option may not work as you expect"));
697 if (Carg)
698 builtin_error (_("warning: -C option may not work as you expect"));
699
700 /* If we get here, we need to build a compspec and evaluate it. */
701 cs = compspec_create ();
702 cs->actions = acts;
703 cs->options = copts;
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;
715 sl = gen_compspec_completions (cs, "compgen", word, 0, 0, 0);
716
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
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 {
730 matches = rl_completion_matches (word, rl_filename_completion_function);
731 sl = completions_to_stringlist (matches);
732 strvec_dispose (matches);
733 }
734
735 if (sl)
736 {
737 if (sl->list && sl->list_len)
738 {
739 rval = EXECUTION_SUCCESS;
740 strlist_print (sl, (char *)NULL);
741 }
742 strlist_dispose (sl);
743 }
744
745 compspec_dispose (cs);
746 return (rval);
747 }
748
749 $BUILTIN compopt
750 $DEPENDS_ON PROGRAMMABLE_COMPLETION
751 $FUNCTION compopt_builtin
752 $SHORT_DOC compopt [-o|+o option] [-DE] [name ...]
753 Modify or display completion options.
754
755 Modify the completion options for each NAME, or, if no NAMEs are supplied,
756 the completion currently being executed. If no OPTIONs are given, print
757 the completion options for each NAME or the current completion specification.
758
759 Options:
760 -o option Set completion option OPTION for each NAME
761 -D Change options for the "default" command completion
762 -E Change options for the "empty" command completion
763
764 Using `+o' instead of `-o' turns off the specified option.
765
766 Arguments:
767
768 Each NAME refers to a command for which a completion specification must
769 have previously been defined using the `complete' builtin. If no NAMEs
770 are supplied, compopt must be called by a function currently generating
771 completions, and the options for that currently-executing completion
772 generator are modified.
773
774 Exit Status:
775 Returns success unless an invalid option is supplied or NAME does not
776 have a completion specification defined.
777 $END
778
779 int
780 compopt_builtin (list)
781 WORD_LIST *list;
782 {
783 int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag;
784 WORD_LIST *l, *wl;
785 COMPSPEC *cs;
786
787 opts_on = opts_off = Eflag = Dflag = 0;
788 ret = EXECUTION_SUCCESS;
789
790 reset_internal_getopt ();
791 while ((opt = internal_getopt (list, "+o:DE")) != EOF)
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;
806 case 'D':
807 Dflag = 1;
808 break;
809 case 'E':
810 Eflag = 1;
811 break;
812 default:
813 builtin_usage ();
814 return (EX_USAGE);
815 }
816 }
817 list = loptend;
818
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)
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
848 for (l = wl ? wl : list; l; l = l->next)
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 }