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