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} 623