]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/complete.def
Imported from ../bash-3.2.48.tar.gz.
[thirdparty/bash.git] / builtins / complete.def
CommitLineData
bb70624e
JA
1This file is complete.def, from which is created complete.c.
2It implements the builtins "complete" and "compgen" in Bash.
3
b80f6443 4Copyright (C) 1999-2003 Free Software Foundation, Inc.
bb70624e
JA
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21
22$PRODUCES complete.c
23
24$BUILTIN complete
25$DEPENDS_ON PROGRAMMABLE_COMPLETION
26$FUNCTION complete_builtin
7117c2d2 27$SHORT_DOC complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...]
bb70624e
JA
28For each NAME, specify how arguments are to be completed.
29If the -p option is supplied, or if no options are supplied, existing
30completion specifications are printed in a way that allows them to be
31reused as input. The -r option removes a completion specification for
32each NAME, or, if no NAMEs are supplied, all completion specifications.
33$END
34
35#include <config.h>
36
37#include <stdio.h>
38
39#include "../bashtypes.h"
40
41#if defined (HAVE_UNISTD_H)
42# include <unistd.h>
43#endif
44
45#include "../bashansi.h"
b80f6443 46#include "../bashintl.h"
bb70624e
JA
47
48#include "../shell.h"
49#include "../builtins.h"
50#include "../pcomplete.h"
b80f6443 51#include "../bashline.h"
bb70624e
JA
52
53#include "common.h"
54#include "bashgetopt.h"
55
f73dda09
JA
56#include <readline/readline.h>
57
bb70624e
JA
58#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
59
f73dda09
JA
60static int find_compact __P((char *));
61static int find_compopt __P((char *));
62
63static int build_actions __P((WORD_LIST *, int *, int *, unsigned long *, unsigned long *));
64
65static int remove_cmd_completions __P((WORD_LIST *));
bb70624e 66
7117c2d2
JA
67static int print_one_completion __P((char *, COMPSPEC *));
68static int print_compitem __P((BUCKET_CONTENTS *));
f73dda09
JA
69static void print_all_completions __P((void));
70static int print_cmd_completions __P((WORD_LIST *));
bb70624e 71
7117c2d2 72static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
bb70624e
JA
73
74static struct _compacts {
75 char *actname;
76 int actflag;
77 int actopt;
78} compacts[] = {
79 { "alias", CA_ALIAS, 'a' },
80 { "arrayvar", CA_ARRAYVAR, 0 },
81 { "binding", CA_BINDING, 0 },
82 { "builtin", CA_BUILTIN, 'b' },
83 { "command", CA_COMMAND, 'c' },
84 { "directory", CA_DIRECTORY, 'd' },
85 { "disabled", CA_DISABLED, 0 },
86 { "enabled", CA_ENABLED, 0 },
87 { "export", CA_EXPORT, 'e' },
88 { "file", CA_FILE, 'f' },
89 { "function", CA_FUNCTION, 0 },
90 { "helptopic", CA_BUILTIN, 0 }, /* for now */
91 { "hostname", CA_HOSTNAME, 0 },
f73dda09 92 { "group", CA_GROUP, 'g' },
bb70624e
JA
93 { "job", CA_JOB, 'j' },
94 { "keyword", CA_KEYWORD, 'k' },
95 { "running", CA_RUNNING, 0 },
7117c2d2 96 { "service", CA_SERVICE, 's' },
bb70624e
JA
97 { "setopt", CA_SETOPT, 0 },
98 { "shopt", CA_SHOPT, 0 },
99 { "signal", CA_SIGNAL, 0 },
100 { "stopped", CA_STOPPED, 0 },
101 { "user", CA_USER, 'u' },
102 { "variable", CA_VARIABLE, 'v' },
103 { (char *)NULL, 0, 0 },
104};
105
7117c2d2 106/* This should be a STRING_INT_ALIST */
28ef6c31
JA
107static struct _compopt {
108 char *optname;
109 int optflag;
110} compopts[] = {
b80f6443 111 { "bashdefault", COPT_BASHDEFAULT },
28ef6c31
JA
112 { "default", COPT_DEFAULT },
113 { "dirnames", COPT_DIRNAMES },
114 { "filenames",COPT_FILENAMES},
7117c2d2 115 { "nospace", COPT_NOSPACE },
b80f6443 116 { "plusdirs", COPT_PLUSDIRS },
28ef6c31
JA
117 { (char *)NULL, 0 },
118};
119
bb70624e
JA
120static int
121find_compact (name)
122 char *name;
123{
124 register int i;
125
126 for (i = 0; compacts[i].actname; i++)
127 if (STREQ (name, compacts[i].actname))
128 return i;
129 return -1;
130}
131
28ef6c31
JA
132static int
133find_compopt (name)
134 char *name;
135{
136 register int i;
137
138 for (i = 0; compopts[i].optname; i++)
139 if (STREQ (name, compopts[i].optname))
140 return i;
141 return -1;
142}
143
144/* Build the actions and compspec options from the options specified in LIST.
145 ACTP is a pointer to an unsigned long in which to place the bitmap of
146 actions. OPTP is a pointer to an unsigned long in which to place the
147 btmap of compspec options (arguments to `-o'). PP, if non-null, gets 1
148 if -p is supplied; RP, if non-null, gets 1 if -r is supplied.
149 If either is null, the corresponding option generates an error.
150 This also sets variables corresponding to options that take arguments as
151 a side effect; the caller should ensure that those variables are set to
152 NULL before calling build_actions. Return value:
bb70624e
JA
153 EX_USAGE = bad option
154 EXECUTION_SUCCESS = some options supplied
155 EXECUTION_FAILURE = no options supplied
156*/
157
158static int
28ef6c31 159build_actions (list, pp, rp, actp, optp)
bb70624e
JA
160 WORD_LIST *list;
161 int *pp, *rp;
28ef6c31 162 unsigned long *actp, *optp;
bb70624e 163{
f73dda09 164 int opt, ind, opt_given;
28ef6c31 165 unsigned long acts, copts;
bb70624e 166
28ef6c31 167 acts = copts = (unsigned long)0L;
bb70624e
JA
168 opt_given = 0;
169
170 reset_internal_getopt ();
7117c2d2 171 while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:")) != -1)
bb70624e
JA
172 {
173 opt_given = 1;
174 switch (opt)
175 {
176 case 'r':
177 if (rp)
178 {
179 *rp = 1;
180 break;
181 }
182 else
183 {
7117c2d2 184 sh_invalidopt ("-r");
bb70624e
JA
185 builtin_usage ();
186 return (EX_USAGE);
187 }
188
189 case 'p':
190 if (pp)
191 {
192 *pp = 1;
193 break;
194 }
195 else
196 {
7117c2d2 197 sh_invalidopt ("-p");
bb70624e
JA
198 builtin_usage ();
199 return (EX_USAGE);
200 }
201
202 case 'a':
203 acts |= CA_ALIAS;
204 break;
205 case 'b':
206 acts |= CA_BUILTIN;
207 break;
208 case 'c':
209 acts |= CA_COMMAND;
210 break;
211 case 'd':
212 acts |= CA_DIRECTORY;
213 break;
214 case 'e':
215 acts |= CA_EXPORT;
216 break;
217 case 'f':
218 acts |= CA_FILE;
219 break;
f73dda09
JA
220 case 'g':
221 acts |= CA_GROUP;
222 break;
bb70624e
JA
223 case 'j':
224 acts |= CA_JOB;
225 break;
226 case 'k':
227 acts |= CA_KEYWORD;
228 break;
7117c2d2
JA
229 case 's':
230 acts |= CA_SERVICE;
231 break;
bb70624e
JA
232 case 'u':
233 acts |= CA_USER;
234 break;
235 case 'v':
236 acts |= CA_VARIABLE;
237 break;
28ef6c31
JA
238 case 'o':
239 ind = find_compopt (list_optarg);
240 if (ind < 0)
241 {
7117c2d2 242 sh_invalidoptname (list_optarg);
28ef6c31
JA
243 return (EX_USAGE);
244 }
245 copts |= compopts[ind].optflag;
246 break;
bb70624e
JA
247 case 'A':
248 ind = find_compact (list_optarg);
249 if (ind < 0)
250 {
b80f6443 251 builtin_error (_("%s: invalid action name"), list_optarg);
bb70624e
JA
252 return (EX_USAGE);
253 }
254 acts |= compacts[ind].actflag;
255 break;
256 case 'C':
257 Carg = list_optarg;
258 break;
259 case 'F':
260 Farg = list_optarg;
261 break;
262 case 'G':
263 Garg = list_optarg;
264 break;
265 case 'P':
266 Parg = list_optarg;
267 break;
268 case 'S':
269 Sarg = list_optarg;
270 break;
271 case 'W':
272 Warg = list_optarg;
273 break;
274 case 'X':
275 Xarg = list_optarg;
276 break;
277 default:
278 builtin_usage ();
279 return (EX_USAGE);
280 }
281 }
282
283 *actp = acts;
28ef6c31
JA
284 *optp = copts;
285
bb70624e
JA
286 return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
287}
288
289/* Add, remove, and display completion specifiers. */
290int
291complete_builtin (list)
292 WORD_LIST *list;
293{
294 int opt_given, pflag, rflag, rval;
28ef6c31 295 unsigned long acts, copts;
bb70624e
JA
296 COMPSPEC *cs;
297
298 if (list == 0)
299 {
300 print_all_completions ();
301 return (EXECUTION_SUCCESS);
302 }
303
304 opt_given = pflag = rflag = 0;
28ef6c31 305 acts = copts = (unsigned long)0L;
7117c2d2 306 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
bb70624e
JA
307 cs = (COMPSPEC *)NULL;
308
309 /* Build the actions from the arguments. Also sets the [A-Z]arg variables
310 as a side effect if they are supplied as options. */
28ef6c31 311 rval = build_actions (list, &pflag, &rflag, &acts, &copts);
bb70624e
JA
312 if (rval == EX_USAGE)
313 return (rval);
314 opt_given = rval != EXECUTION_FAILURE;
315
316 list = loptend;
317
318 /* -p overrides everything else */
319 if (pflag || (list == 0 && opt_given == 0))
320 {
321 if (list == 0)
322 {
323 print_all_completions ();
324 return (EXECUTION_SUCCESS);
325 }
326 return (print_cmd_completions (list));
327 }
328
329 /* next, -r overrides everything else. */
330 if (rflag)
331 {
332 if (list == 0)
333 {
7117c2d2 334 progcomp_flush ();
bb70624e
JA
335 return (EXECUTION_SUCCESS);
336 }
337 return (remove_cmd_completions (list));
338 }
339
340 if (list == 0 && opt_given)
341 {
342 builtin_usage ();
343 return (EX_USAGE);
344 }
345
346 /* If we get here, we need to build a compspec and add it for each
347 remaining argument. */
7117c2d2 348 cs = compspec_create ();
bb70624e 349 cs->actions = acts;
28ef6c31 350 cs->options = copts;
bb70624e
JA
351
352 cs->globpat = STRDUP (Garg);
353 cs->words = STRDUP (Warg);
354 cs->prefix = STRDUP (Parg);
355 cs->suffix = STRDUP (Sarg);
356 cs->funcname = STRDUP (Farg);
357 cs->command = STRDUP (Carg);
358 cs->filterpat = STRDUP (Xarg);
359
360 for (rval = EXECUTION_SUCCESS ; list; list = list->next)
361 {
362 /* Add CS as the compspec for the specified commands. */
7117c2d2 363 if (progcomp_insert (list->word->word, cs) == 0)
28ef6c31 364 rval = EXECUTION_FAILURE;
bb70624e
JA
365 }
366
367 return (rval);
368}
369
370static int
371remove_cmd_completions (list)
372 WORD_LIST *list;
373{
374 WORD_LIST *l;
375 int ret;
376
377 for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
378 {
7117c2d2 379 if (progcomp_remove (l->word->word) == 0)
bb70624e 380 {
b80f6443 381 builtin_error (_("%s: no completion specification"), l->word->word);
bb70624e
JA
382 ret = EXECUTION_FAILURE;
383 }
384 }
385 return ret;
386}
387
388#define SQPRINTARG(a, f) \
389 do { \
390 if (a) \
391 { \
28ef6c31 392 x = sh_single_quote (a); \
bb70624e
JA
393 printf ("%s %s ", f, x); \
394 free (x); \
395 } \
396 } while (0)
397
398#define PRINTARG(a, f) \
399 do { \
400 if (a) \
401 printf ("%s %s ", f, a); \
402 } while (0)
403
404#define PRINTOPT(a, f) \
405 do { \
406 if (acts & a) \
407 printf ("%s ", f); \
408 } while (0)
409
410#define PRINTACT(a, f) \
411 do { \
412 if (acts & a) \
413 printf ("-A %s ", f); \
414 } while (0)
415
28ef6c31
JA
416#define PRINTCOMPOPT(a, f) \
417 do { \
418 if (copts & a) \
419 printf ("-o %s ", f); \
420 } while (0)
421
7117c2d2 422static int
bb70624e
JA
423print_one_completion (cmd, cs)
424 char *cmd;
425 COMPSPEC *cs;
426{
28ef6c31 427 unsigned long acts, copts;
bb70624e
JA
428 char *x;
429
430 printf ("complete ");
431
28ef6c31
JA
432 copts = cs->options;
433
434 /* First, print the -o options. */
b80f6443 435 PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
28ef6c31
JA
436 PRINTCOMPOPT (COPT_DEFAULT, "default");
437 PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
438 PRINTCOMPOPT (COPT_FILENAMES, "filenames");
7117c2d2 439 PRINTCOMPOPT (COPT_NOSPACE, "nospace");
b80f6443 440 PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
28ef6c31 441
bb70624e
JA
442 acts = cs->actions;
443
28ef6c31 444 /* simple flags next */
bb70624e
JA
445 PRINTOPT (CA_ALIAS, "-a");
446 PRINTOPT (CA_BUILTIN, "-b");
447 PRINTOPT (CA_COMMAND, "-c");
448 PRINTOPT (CA_DIRECTORY, "-d");
449 PRINTOPT (CA_EXPORT, "-e");
450 PRINTOPT (CA_FILE, "-f");
f73dda09 451 PRINTOPT (CA_GROUP, "-g");
bb70624e 452 PRINTOPT (CA_JOB, "-j");
7117c2d2
JA
453 PRINTOPT (CA_KEYWORD, "-k");
454 PRINTOPT (CA_SERVICE, "-s");
bb70624e
JA
455 PRINTOPT (CA_USER, "-u");
456 PRINTOPT (CA_VARIABLE, "-v");
457
458 /* now the rest of the actions */
459 PRINTACT (CA_ARRAYVAR, "arrayvar");
460 PRINTACT (CA_BINDING, "binding");
461 PRINTACT (CA_DISABLED, "disabled");
462 PRINTACT (CA_ENABLED, "enabled");
463 PRINTACT (CA_FUNCTION, "function");
464 PRINTACT (CA_HELPTOPIC, "helptopic");
465 PRINTACT (CA_HOSTNAME, "hostname");
466 PRINTACT (CA_RUNNING, "running");
467 PRINTACT (CA_SETOPT, "setopt");
468 PRINTACT (CA_SHOPT, "shopt");
469 PRINTACT (CA_SIGNAL, "signal");
470 PRINTACT (CA_STOPPED, "stopped");
471
472 /* now the rest of the arguments */
473
474 /* arguments that require quoting */
475 SQPRINTARG (cs->globpat, "-G");
476 SQPRINTARG (cs->words, "-W");
477 SQPRINTARG (cs->prefix, "-P");
478 SQPRINTARG (cs->suffix, "-S");
479 SQPRINTARG (cs->filterpat, "-X");
480
481 /* simple arguments that don't require quoting */
482 PRINTARG (cs->funcname, "-F");
483 PRINTARG (cs->command, "-C");
484
485 printf ("%s\n", cmd);
7117c2d2
JA
486
487 return (0);
488}
489
490static int
491print_compitem (item)
492 BUCKET_CONTENTS *item;
493{
494 COMPSPEC *cs;
495 char *cmd;
496
497 cmd = item->key;
498 cs = (COMPSPEC *)item->data;
499
500 return (print_one_completion (cmd, cs));
bb70624e
JA
501}
502
503static void
504print_all_completions ()
505{
7117c2d2 506 progcomp_walk (print_compitem);
bb70624e
JA
507}
508
509static int
510print_cmd_completions (list)
511 WORD_LIST *list;
512{
513 WORD_LIST *l;
514 COMPSPEC *cs;
515 int ret;
516
517 for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
518 {
7117c2d2 519 cs = progcomp_search (l->word->word);
bb70624e 520 if (cs)
28ef6c31 521 print_one_completion (l->word->word, cs);
bb70624e
JA
522 else
523 {
b80f6443 524 builtin_error (_("%s: no completion specification"), l->word->word);
bb70624e
JA
525 ret = EXECUTION_FAILURE;
526 }
527 }
528 return (ret);
529}
530
531$BUILTIN compgen
532$DEPENDS_ON PROGRAMMABLE_COMPLETION
533$FUNCTION compgen_builtin
7117c2d2 534$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [word]
bb70624e
JA
535Display the possible completions depending on the options. Intended
536to be used from within a shell function generating possible completions.
537If the optional WORD argument is supplied, matches against WORD are
538generated.
539$END
540
541int
542compgen_builtin (list)
543 WORD_LIST *list;
544{
545 int rval;
28ef6c31 546 unsigned long acts, copts;
bb70624e
JA
547 COMPSPEC *cs;
548 STRINGLIST *sl;
b80f6443 549 char *word, **matches;
bb70624e
JA
550
551 if (list == 0)
552 return (EXECUTION_SUCCESS);
553
28ef6c31 554 acts = copts = (unsigned long)0L;
7117c2d2 555 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
bb70624e
JA
556 cs = (COMPSPEC *)NULL;
557
558 /* Build the actions from the arguments. Also sets the [A-Z]arg variables
559 as a side effect if they are supplied as options. */
28ef6c31 560 rval = build_actions (list, (int *)NULL, (int *)NULL, &acts, &copts);
bb70624e
JA
561 if (rval == EX_USAGE)
562 return (rval);
563 if (rval == EXECUTION_FAILURE)
564 return (EXECUTION_SUCCESS);
565
566 list = loptend;
567
568 word = (list && list->word) ? list->word->word : "";
569
570 if (Farg)
b80f6443 571 builtin_error (_("warning: -F option may not work as you expect"));
bb70624e 572 if (Carg)
b80f6443 573 builtin_error (_("warning: -C option may not work as you expect"));
bb70624e
JA
574
575 /* If we get here, we need to build a compspec and evaluate it. */
7117c2d2 576 cs = compspec_create ();
bb70624e 577 cs->actions = acts;
28ef6c31 578 cs->options = copts;
bb70624e
JA
579 cs->refcount = 1;
580
581 cs->globpat = STRDUP (Garg);
582 cs->words = STRDUP (Warg);
583 cs->prefix = STRDUP (Parg);
584 cs->suffix = STRDUP (Sarg);
585 cs->funcname = STRDUP (Farg);
586 cs->command = STRDUP (Carg);
587 cs->filterpat = STRDUP (Xarg);
588
589 rval = EXECUTION_FAILURE;
590 sl = gen_compspec_completions (cs, "compgen", word, 0, 0);
f73dda09 591
b80f6443
JA
592 /* If the compspec wants the bash default completions, temporarily
593 turn off programmable completion and call the bash completion code. */
594 if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT))
595 {
596 matches = bash_default_completion (word, 0, 0, 0, 0);
597 sl = completions_to_stringlist (matches);
598 strvec_dispose (matches);
599 }
600
f73dda09
JA
601 /* This isn't perfect, but it's the best we can do, given what readline
602 exports from its set of completion utility functions. */
603 if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
604 {
f73dda09
JA
605 matches = rl_completion_matches (word, rl_filename_completion_function);
606 sl = completions_to_stringlist (matches);
7117c2d2 607 strvec_dispose (matches);
f73dda09
JA
608 }
609
bb70624e
JA
610 if (sl)
611 {
f73dda09 612 if (sl->list && sl->list_len)
bb70624e
JA
613 {
614 rval = EXECUTION_SUCCESS;
7117c2d2 615 strlist_print (sl, (char *)NULL);
bb70624e 616 }
7117c2d2 617 strlist_dispose (sl);
bb70624e
JA
618 }
619
7117c2d2 620 compspec_dispose (cs);
bb70624e
JA
621 return (rval);
622}