source: vendor/bash/3.1/builtins/complete.def

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

File size: 14.7 KB
Line 
1This file is complete.def, from which is created complete.c.
2It implements the builtins "complete" and "compgen" in Bash.
3
4Copyright (C) 1999-2003 Free Software Foundation, Inc.
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
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 ...]
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"
46#include "../bashintl.h"
47
48#include "../shell.h"
49#include "../builtins.h"
50#include "../pcomplete.h"
51#include "../bashline.h"
52
53#include "common.h"
54#include "bashgetopt.h"
55
56#include <readline/readline.h>
57
58#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
59
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 *));
66
67static int print_one_completion __P((char *, COMPSPEC *));
68static int print_compitem __P((BUCKET_CONTENTS *));
69static void print_all_completions __P((void));
70static int print_cmd_completions __P((WORD_LIST *));
71
72static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
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 },
92 { "group", CA_GROUP, 'g' },
93 { "job", CA_JOB, 'j' },
94 { "keyword", CA_KEYWORD, 'k' },
95 { "running", CA_RUNNING, 0 },
96 { "service", CA_SERVICE, 's' },
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
106/* This should be a STRING_INT_ALIST */
107static struct _compopt {
108 char *optname;
109 int optflag;
110} compopts[] = {
111 { "bashdefault", COPT_BASHDEFAULT },
112 { "default", COPT_DEFAULT },
113 { "dirnames", COPT_DIRNAMES },
114 { "filenames",COPT_FILENAMES},
115 { "nospace", COPT_NOSPACE },
116 { "plusdirs", COPT_PLUSDIRS },
117 { (char *)NULL, 0 },
118};
119
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
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:
153 EX_USAGE = bad option
154 EXECUTION_SUCCESS = some options supplied
155 EXECUTION_FAILURE = no options supplied
156*/
157
158static int
159build_actions (list, pp, rp, actp, optp)
160 WORD_LIST *list;
161 int *pp, *rp;
162 unsigned long *actp, *optp;
163{
164 int opt, ind, opt_given;
165 unsigned long acts, copts;
166
167 acts = copts = (unsigned long)0L;
168 opt_given = 0;
169
170 reset_internal_getopt ();
171 while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:")) != -1)
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 {
184 sh_invalidopt ("-r");
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 {
197 sh_invalidopt ("-p");
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;
220 case 'g':
221 acts |= CA_GROUP;
222 break;
223 case 'j':
224 acts |= CA_JOB;
225 break;
226 case 'k':
227 acts |= CA_KEYWORD;
228 break;
229 case 's':
230 acts |= CA_SERVICE;
231 break;
232 case 'u':
233 acts |= CA_USER;
234 break;
235 case 'v':
236 acts |= CA_VARIABLE;
237 break;
238 case 'o':
239 ind = find_compopt (list_optarg);
240 if (ind < 0)
241 {
242 sh_invalidoptname (list_optarg);
243 return (EX_USAGE);
244 }
245 copts |= compopts[ind].optflag;
246 break;
247 case 'A':
248 ind = find_compact (list_optarg);
249 if (ind < 0)
250 {
251 builtin_error (_("%s: invalid action name"), list_optarg);
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;
284 *optp = copts;
285
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;
295 unsigned long acts, copts;
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;
305 acts = copts = (unsigned long)0L;
306 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
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. */
311 rval = build_actions (list, &pflag, &rflag, &acts, &copts);
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 {
334 progcomp_flush ();
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. */
348 cs = compspec_create ();
349 cs->actions = acts;
350 cs->options = copts;
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. */
363 if (progcomp_insert (list->word->word, cs) == 0)
364 rval = EXECUTION_FAILURE;
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 {
379 if (progcomp_remove (l->word->word) == 0)
380 {
381 builtin_error (_("%s: no completion specification"), l->word->word);
382 ret = EXECUTION_FAILURE;
383 }
384 }
385 return ret;
386}
387
388#define SQPRINTARG(a, f) \
389 do { \
390 if (a) \
391 { \
392 x = sh_single_quote (a); \
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
416#define PRINTCOMPOPT(a, f) \
417 do { \
418 if (copts & a) \
419 printf ("-o %s ", f); \
420 } while (0)
421
422static int
423print_one_completion (cmd, cs)
424 char *cmd;
425 COMPSPEC *cs;
426{
427 unsigned long acts, copts;
428 char *x;
429
430 printf ("complete ");
431
432 copts = cs->options;
433
434 /* First, print the -o options. */
435 PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
436 PRINTCOMPOPT (COPT_DEFAULT, "default");
437 PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
438 PRINTCOMPOPT (COPT_FILENAMES, "filenames");
439 PRINTCOMPOPT (COPT_NOSPACE, "nospace");
440 PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
441
442 acts = cs->actions;
443
444 /* simple flags next */
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");
451 PRINTOPT (CA_GROUP, "-g");
452 PRINTOPT (CA_JOB, "-j");
453 PRINTOPT (CA_KEYWORD, "-k");
454 PRINTOPT (CA_SERVICE, "-s");
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);
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));
501}
502
503static void
504print_all_completions ()
505{
506 progcomp_walk (print_compitem);
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 {
519 cs = progcomp_search (l->word->word);
520 if (cs)
521 print_one_completion (l->word->word, cs);
522 else
523 {
524 builtin_error (_("%s: no completion specification"), l->word->word);
525 ret = EXECUTION_FAILURE;
526 }
527 }
528 return (ret);
529}
530
531$BUILTIN compgen
532$DEPENDS_ON PROGRAMMABLE_COMPLETION
533$FUNCTION compgen_builtin
534$SHORT_DOC compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [word]
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;
546 unsigned long acts, copts;
547 COMPSPEC *cs;
548 STRINGLIST *sl;
549 char *word, **matches;
550
551 if (list == 0)
552 return (EXECUTION_SUCCESS);
553
554 acts = copts = (unsigned long)0L;
555 Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
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. */
560 rval = build_actions (list, (int *)NULL, (int *)NULL, &acts, &copts);
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)
571 builtin_error (_("warning: -F option may not work as you expect"));
572 if (Carg)
573 builtin_error (_("warning: -C option may not work as you expect"));
574
575 /* If we get here, we need to build a compspec and evaluate it. */
576 cs = compspec_create ();
577 cs->actions = acts;
578 cs->options = copts;
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);
591
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
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 {
605 matches = rl_completion_matches (word, rl_filename_completion_function);
606 sl = completions_to_stringlist (matches);
607 strvec_dispose (matches);
608 }
609
610 if (sl)
611 {
612 if (sl->list && sl->list_len)
613 {
614 rval = EXECUTION_SUCCESS;
615 strlist_print (sl, (char *)NULL);
616 }
617 strlist_dispose (sl);
618 }
619
620 compspec_dispose (cs);
621 return (rval);
622}
Note: See TracBrowser for help on using the repository browser.