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