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