]> git.ipfire.org Git - thirdparty/bash.git/blob - pcomplete.c
Imported from ../bash-2.05b.tar.gz.
[thirdparty/bash.git] / pcomplete.c
1 /* pcomplete.c - functions to generate lists of matches for programmable
2 completion. */
3
4 /* Copyright (C) 1999-2002 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
21
22 #include <config.h>
23
24 #if defined (PROGRAMMABLE_COMPLETION)
25
26 #include "bashtypes.h"
27 #include "posixstat.h"
28
29 #if defined (HAVE_UNISTD_H)
30 # include <unistd.h>
31 #endif
32
33 #include <signal.h>
34
35 #if defined (PREFER_STDARG)
36 # include <stdarg.h>
37 #else
38 # include <varargs.h>
39 #endif
40
41 #include <stdio.h>
42 #include "bashansi.h"
43
44 #include "shell.h"
45 #include "pcomplete.h"
46 #include "alias.h"
47 #include "bashline.h"
48 #include "execute_cmd.h"
49 #include "pathexp.h"
50
51 #if defined (JOB_CONTROL)
52 # include "jobs.h"
53 #endif
54
55 #if !defined (NSIG)
56 # include "trap.h"
57 #endif
58
59 #include "builtins.h"
60 #include "builtins/common.h"
61
62 #include <glob/glob.h>
63 #include <glob/strmatch.h>
64
65 #include <readline/rlconf.h>
66 #include <readline/readline.h>
67 #include <readline/history.h>
68
69 #ifdef STRDUP
70 # undef STRDUP
71 #endif
72 #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
73
74 typedef SHELL_VAR **SVFUNC ();
75
76 #ifndef HAVE_STRPBRK
77 extern char *strpbrk __P((char *, char *));
78 #endif
79
80 extern int array_needs_making;
81 extern STRING_INT_ALIST word_token_alist[];
82 extern char *signal_names[];
83
84 #if defined (DEBUG)
85 #if defined (PREFER_STDARG)
86 static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
87 #endif
88 #endif /* DEBUG */
89
90 static int it_init_joblist __P((ITEMLIST *, int));
91
92 static int it_init_aliases __P((ITEMLIST *));
93 static int it_init_arrayvars __P((ITEMLIST *));
94 static int it_init_bindings __P((ITEMLIST *));
95 static int it_init_builtins __P((ITEMLIST *));
96 static int it_init_disabled __P((ITEMLIST *));
97 static int it_init_enabled __P((ITEMLIST *));
98 static int it_init_exported __P((ITEMLIST *));
99 static int it_init_functions __P((ITEMLIST *));
100 static int it_init_hostnames __P((ITEMLIST *));
101 static int it_init_jobs __P((ITEMLIST *));
102 static int it_init_running __P((ITEMLIST *));
103 static int it_init_stopped __P((ITEMLIST *));
104 static int it_init_keywords __P((ITEMLIST *));
105 static int it_init_signals __P((ITEMLIST *));
106 static int it_init_variables __P((ITEMLIST *));
107 static int it_init_setopts __P((ITEMLIST *));
108 static int it_init_shopts __P((ITEMLIST *));
109
110 static int shouldexp_filterpat __P((char *));
111 static char *preproc_filterpat __P((char *, char *));
112
113 static void init_itemlist_from_varlist __P((ITEMLIST *, SVFUNC *));
114
115 static STRINGLIST *gen_matches_from_itemlist __P((ITEMLIST *, const char *));
116 static STRINGLIST *gen_action_completions __P((COMPSPEC *, const char *));
117 static STRINGLIST *gen_globpat_matches __P((COMPSPEC *, const char *));
118 static STRINGLIST *gen_wordlist_matches __P((COMPSPEC *, const char *));
119 static STRINGLIST *gen_shell_function_matches __P((COMPSPEC *, const char *,
120 char *, int, WORD_LIST *,
121 int, int));
122 static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *, char *,
123 int, WORD_LIST *, int, int));
124
125 static char *pcomp_filename_completion_function __P((const char *, int));
126
127 #if defined (ARRAY_VARS)
128 static SHELL_VAR *bind_comp_words __P((WORD_LIST *));
129 #endif
130 static void bind_compfunc_variables __P((char *, int, WORD_LIST *, int, int));
131 static void unbind_compfunc_variables __P((int));
132 static WORD_LIST *build_arg_list __P((char *, const char *, WORD_LIST *, int));
133 static WORD_LIST *command_line_to_word_list __P((char *, int, int, int *, int *));
134
135 #ifdef DEBUG
136 static int progcomp_debug = 0;
137 #endif
138
139 int prog_completion_enabled = 1;
140
141 /* These are used to manage the arrays of strings for possible completions. */
142 ITEMLIST it_aliases = { 0, it_init_aliases, (STRINGLIST *)0 };
143 ITEMLIST it_arrayvars = { LIST_DYNAMIC, it_init_arrayvars, (STRINGLIST *)0 };
144 ITEMLIST it_bindings = { 0, it_init_bindings, (STRINGLIST *)0 };
145 ITEMLIST it_builtins = { 0, it_init_builtins, (STRINGLIST *)0 };
146 ITEMLIST it_commands = { LIST_DYNAMIC }; /* unused */
147 ITEMLIST it_directories = { LIST_DYNAMIC }; /* unused */
148 ITEMLIST it_disabled = { 0, it_init_disabled, (STRINGLIST *)0 };
149 ITEMLIST it_enabled = { 0, it_init_enabled, (STRINGLIST *)0 };
150 ITEMLIST it_exports = { LIST_DYNAMIC, it_init_exported, (STRINGLIST *)0 };
151 ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */
152 ITEMLIST it_functions = { 0, it_init_functions, (STRINGLIST *)0 };
153 ITEMLIST it_hostnames = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 };
154 ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */
155 ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 };
156 ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 };
157 ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 };
158 ITEMLIST it_services = { LIST_DYNAMIC }; /* unused */
159 ITEMLIST it_setopts = { 0, it_init_setopts, (STRINGLIST *)0 };
160 ITEMLIST it_shopts = { 0, it_init_shopts, (STRINGLIST *)0 };
161 ITEMLIST it_signals = { 0, it_init_signals, (STRINGLIST *)0 };
162 ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
163 ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
164 ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
165
166 #ifdef DEBUG
167 /* Debugging code */
168 static void
169 #if defined (PREFER_STDARG)
170 debug_printf (const char *format, ...)
171 #else
172 debug_printf (format, va_alist)
173 const char *format;
174 va_dcl
175 #endif
176 {
177 va_list args;
178
179 if (progcomp_debug == 0)
180 return;
181
182 SH_VA_START (args, format);
183
184 fprintf (stdout, "DEBUG: ");
185 vfprintf (stdout, format, args);
186 fprintf (stdout, "\n");
187
188 rl_on_new_line ();
189
190 va_end (args);
191 }
192 #endif
193
194 /* Functions to manage the item lists */
195
196 void
197 set_itemlist_dirty (it)
198 ITEMLIST *it;
199 {
200 it->flags |= LIST_DIRTY;
201 }
202
203 void
204 initialize_itemlist (itp)
205 ITEMLIST *itp;
206 {
207 (*itp->list_getter) (itp);
208 itp->flags |= LIST_INITIALIZED;
209 itp->flags &= ~LIST_DIRTY;
210 }
211
212 void
213 clean_itemlist (itp)
214 ITEMLIST *itp;
215 {
216 STRINGLIST *sl;
217
218 sl = itp->slist;
219 if (sl)
220 {
221 if ((itp->flags & (LIST_DONTFREEMEMBERS|LIST_DONTFREE)) == 0)
222 strvec_flush (sl->list);
223 if ((itp->flags & LIST_DONTFREE) == 0)
224 free (sl->list);
225 free (sl);
226 }
227 itp->slist = (STRINGLIST *)NULL;
228 itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY);
229 }
230
231
232 static int
233 shouldexp_filterpat (s)
234 char *s;
235 {
236 register char *p;
237
238 for (p = s; p && *p; p++)
239 {
240 if (*p == '\\')
241 p++;
242 else if (*p == '&')
243 return 1;
244 }
245 return 0;
246 }
247
248 /* Replace any instance of `&' in PAT with TEXT. Backslash may be used to
249 quote a `&' and inhibit substitution. Returns a new string. This just
250 calls stringlib.c:strcreplace(). */
251 static char *
252 preproc_filterpat (pat, text)
253 char *pat;
254 char *text;
255 {
256 char *ret;
257
258 ret = strcreplace (pat, '&', text, 1);
259 return ret;
260 }
261
262 /* Remove any match of FILTERPAT from SL. A `&' in FILTERPAT is replaced by
263 TEXT. A leading `!' in FILTERPAT negates the pattern; in this case
264 any member of SL->list that does *not* match will be removed. This returns
265 a new STRINGLIST with the matching members of SL *copied*. Any
266 non-matching members of SL->list are *freed*. */
267 STRINGLIST *
268 filter_stringlist (sl, filterpat, text)
269 STRINGLIST *sl;
270 char *filterpat, *text;
271 {
272 int i, m, not;
273 STRINGLIST *ret;
274 char *npat, *t;
275
276 if (sl == 0 || sl->list == 0 || sl->list_len == 0)
277 return sl;
278
279 npat = shouldexp_filterpat (filterpat) ? preproc_filterpat (filterpat, text) : filterpat;
280
281 not = (npat[0] == '!');
282 t = not ? npat + 1 : npat;
283
284 ret = strlist_create (sl->list_size);
285 for (i = 0; i < sl->list_len; i++)
286 {
287 m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);
288 if ((not && m == FNM_NOMATCH) || (not == 0 && m != FNM_NOMATCH))
289 free (sl->list[i]);
290 else
291 ret->list[ret->list_len++] = sl->list[i];
292 }
293
294 ret->list[ret->list_len] = (char *)NULL;
295 if (npat != filterpat)
296 free (npat);
297
298 return ret;
299 }
300
301 /* Turn an array of strings returned by rl_completion_matches into a STRINGLIST.
302 This understands how rl_completion_matches sets matches[0] (the lcd of the
303 strings in the list, unless it's the only match). */
304 STRINGLIST *
305 completions_to_stringlist (matches)
306 char **matches;
307 {
308 STRINGLIST *sl;
309 int mlen, i, n;
310
311 mlen = (matches == 0) ? 0 : strvec_len (matches);
312 sl = strlist_create (mlen + 1);
313
314 if (matches == 0 || matches[0] == 0)
315 return sl;
316
317 if (matches[1] == 0)
318 {
319 sl->list[0] = STRDUP (matches[0]);
320 sl->list[sl->list_len = 1] = (char *)NULL;
321 return sl;
322 }
323
324 for (i = 1, n = 0; i < mlen; i++, n++)
325 sl->list[n] = STRDUP (matches[i]);
326 sl->list_len = n;
327 sl->list[n] = (char *)NULL;
328
329 return sl;
330 }
331
332 /* Functions to manage the various ITEMLISTs that we populate internally.
333 The caller is responsible for setting ITP->flags correctly. */
334
335 static int
336 it_init_aliases (itp)
337 ITEMLIST *itp;
338 {
339 #ifdef ALIAS
340 alias_t **alias_list;
341 register int i, n;
342 STRINGLIST *sl;
343
344 alias_list = all_aliases ();
345 if (alias_list == 0)
346 {
347 itp->slist = (STRINGLIST *)NULL;
348 return 0;
349 }
350 for (n = 0; alias_list[n]; n++)
351 ;
352 sl = strlist_create (n+1);
353 for (i = 0; i < n; i++)
354 sl->list[i] = STRDUP (alias_list[i]->name);
355 sl->list[n] = (char *)NULL;
356 sl->list_size = sl->list_len = n;
357 itp->slist = sl;
358 #else
359 itp->slist = (STRINGLIST *)NULL;
360 #endif
361 return 1;
362 }
363
364 static void
365 init_itemlist_from_varlist (itp, svfunc)
366 ITEMLIST *itp;
367 SVFUNC *svfunc;
368 {
369 SHELL_VAR **vlist;
370 STRINGLIST *sl;
371 register int i, n;
372
373 vlist = (*svfunc) ();
374 for (n = 0; vlist[n]; n++)
375 ;
376 sl = strlist_create (n+1);
377 for (i = 0; i < n; i++)
378 sl->list[i] = savestring (vlist[i]->name);
379 sl->list[sl->list_len = n] = (char *)NULL;
380 itp->slist = sl;
381 }
382
383 static int
384 it_init_arrayvars (itp)
385 ITEMLIST *itp;
386 {
387 #if defined (ARRAY_VARS)
388 init_itemlist_from_varlist (itp, all_array_variables);
389 return 1;
390 #else
391 return 0;
392 #endif
393 }
394
395 static int
396 it_init_bindings (itp)
397 ITEMLIST *itp;
398 {
399 char **blist;
400 STRINGLIST *sl;
401
402 /* rl_funmap_names allocates blist, but not its members */
403 blist = (char **)rl_funmap_names (); /* XXX fix const later */
404 sl = strlist_create (0);
405 sl->list = blist;
406 sl->list_size = 0;
407 sl->list_len = strvec_len (sl->list);
408 itp->flags |= LIST_DONTFREEMEMBERS;
409 itp->slist = sl;
410
411 return 0;
412 }
413
414 static int
415 it_init_builtins (itp)
416 ITEMLIST *itp;
417 {
418 STRINGLIST *sl;
419 register int i, n;
420
421 sl = strlist_create (num_shell_builtins);
422 for (i = n = 0; i < num_shell_builtins; i++)
423 if (shell_builtins[i].function)
424 sl->list[n++] = shell_builtins[i].name;
425 sl->list[sl->list_len = n] = (char *)NULL;
426 itp->flags |= LIST_DONTFREEMEMBERS;
427 itp->slist = sl;
428 return 0;
429 }
430
431 static int
432 it_init_enabled (itp)
433 ITEMLIST *itp;
434 {
435 STRINGLIST *sl;
436 register int i, n;
437
438 sl = strlist_create (num_shell_builtins);
439 for (i = n = 0; i < num_shell_builtins; i++)
440 {
441 if (shell_builtins[i].function && (shell_builtins[i].flags & BUILTIN_ENABLED))
442 sl->list[n++] = shell_builtins[i].name;
443 }
444 sl->list[sl->list_len = n] = (char *)NULL;
445 itp->flags |= LIST_DONTFREEMEMBERS;
446 itp->slist = sl;
447 return 0;
448 }
449
450 static int
451 it_init_disabled (itp)
452 ITEMLIST *itp;
453 {
454 STRINGLIST *sl;
455 register int i, n;
456
457 sl = strlist_create (num_shell_builtins);
458 for (i = n = 0; i < num_shell_builtins; i++)
459 {
460 if (shell_builtins[i].function && ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
461 sl->list[n++] = shell_builtins[i].name;
462 }
463 sl->list[sl->list_len = n] = (char *)NULL;
464 itp->flags |= LIST_DONTFREEMEMBERS;
465 itp->slist = sl;
466 return 0;
467 }
468
469 static int
470 it_init_exported (itp)
471 ITEMLIST *itp;
472 {
473 init_itemlist_from_varlist (itp, all_exported_variables);
474 return 0;
475 }
476
477 static int
478 it_init_functions (itp)
479 ITEMLIST *itp;
480 {
481 init_itemlist_from_varlist (itp, all_visible_functions);
482 return 0;
483 }
484
485 static int
486 it_init_hostnames (itp)
487 ITEMLIST *itp;
488 {
489 STRINGLIST *sl;
490
491 sl = strlist_create (0);
492 sl->list = get_hostname_list ();
493 sl->list_len = sl->list ? strvec_len (sl->list) : 0;
494 sl->list_size = sl->list_len;
495 itp->slist = sl;
496 itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE;
497 return 0;
498 }
499
500 static int
501 it_init_joblist (itp, jstate)
502 ITEMLIST *itp;
503 int jstate;
504 {
505 #if defined (JOB_CONTROL)
506 STRINGLIST *sl;
507 register int i;
508 register PROCESS *p;
509 char *s, *t;
510 JOB_STATE js;
511
512 if (jstate == 0)
513 js = JRUNNING;
514 else if (jstate == 1)
515 js = JSTOPPED;
516
517 sl = strlist_create (job_slots);
518 for (i = job_slots - 1; i >= 0; i--)
519 {
520 if (jobs[i] == 0)
521 continue;
522 p = jobs[i]->pipe;
523 if (jstate == -1 || JOBSTATE(i) == js)
524 {
525 s = savestring (p->command);
526 t = strpbrk (s, " \t\n");
527 if (t)
528 *t = '\0';
529 sl->list[sl->list_len++] = s;
530 }
531 }
532 itp->slist = sl;
533 #else
534 itp->slist = (STRINGLIST *)NULL;
535 #endif
536 return 0;
537 }
538
539 static int
540 it_init_jobs (itp)
541 ITEMLIST *itp;
542 {
543 return (it_init_joblist (itp, -1));
544 }
545
546 static int
547 it_init_running (itp)
548 ITEMLIST *itp;
549 {
550 return (it_init_joblist (itp, 0));
551 }
552
553 static int
554 it_init_stopped (itp)
555 ITEMLIST *itp;
556 {
557 return (it_init_joblist (itp, 1));
558 }
559
560 static int
561 it_init_keywords (itp)
562 ITEMLIST *itp;
563 {
564 STRINGLIST *sl;
565 register int i, n;
566
567 for (n = 0; word_token_alist[n].word; n++)
568 ;
569 sl = strlist_create (n);
570 for (i = 0; i < n; i++)
571 sl->list[i] = word_token_alist[i].word;
572 sl->list[sl->list_len = i] = (char *)NULL;
573 itp->flags |= LIST_DONTFREEMEMBERS;
574 itp->slist = sl;
575 return 0;
576 }
577
578 static int
579 it_init_signals (itp)
580 ITEMLIST *itp;
581 {
582 STRINGLIST *sl;
583
584 sl = strlist_create (0);
585 sl->list = signal_names;
586 sl->list_len = strvec_len (sl->list);
587 itp->flags |= LIST_DONTFREE;
588 itp->slist = sl;
589 return 0;
590 }
591
592 static int
593 it_init_variables (itp)
594 ITEMLIST *itp;
595 {
596 init_itemlist_from_varlist (itp, all_visible_variables);
597 return 0;
598 }
599
600 static int
601 it_init_setopts (itp)
602 ITEMLIST *itp;
603 {
604 STRINGLIST *sl;
605
606 sl = strlist_create (0);
607 sl->list = get_minus_o_opts ();
608 sl->list_len = strvec_len (sl->list);
609 itp->slist = sl;
610 itp->flags |= LIST_DONTFREEMEMBERS;
611 return 0;
612 }
613
614 static int
615 it_init_shopts (itp)
616 ITEMLIST *itp;
617 {
618 STRINGLIST *sl;
619
620 sl = strlist_create (0);
621 sl->list = get_shopt_options ();
622 sl->list_len = strvec_len (sl->list);
623 itp->slist = sl;
624 itp->flags |= LIST_DONTFREEMEMBERS;
625 return 0;
626 }
627
628 /* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
629 as the list of possibilities. If the itemlist has been marked dirty or
630 it should be regenerated every time, destroy the old STRINGLIST and make a
631 new one before trying the match. */
632 static STRINGLIST *
633 gen_matches_from_itemlist (itp, text)
634 ITEMLIST *itp;
635 const char *text;
636 {
637 STRINGLIST *ret, *sl;
638 int tlen, i, n;
639
640 if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
641 (itp->flags & LIST_INITIALIZED) == 0)
642 {
643 if (itp->flags & (LIST_DIRTY | LIST_DYNAMIC))
644 clean_itemlist (itp);
645 if ((itp->flags & LIST_INITIALIZED) == 0)
646 initialize_itemlist (itp);
647 }
648 if (itp->slist == 0)
649 return ((STRINGLIST *)NULL);
650 ret = strlist_create (itp->slist->list_len+1);
651 sl = itp->slist;
652 tlen = STRLEN (text);
653 for (i = n = 0; i < sl->list_len; i++)
654 {
655 if (tlen == 0 || STREQN (sl->list[i], text, tlen))
656 ret->list[n++] = STRDUP (sl->list[i]);
657 }
658 ret->list[ret->list_len = n] = (char *)NULL;
659 return ret;
660 }
661
662 /* A wrapper for rl_filename_completion_function that dequotes the filename
663 before attempting completions. */
664 static char *
665 pcomp_filename_completion_function (text, state)
666 const char *text;
667 int state;
668 {
669 static char *dfn; /* dequoted filename */
670 int qc;
671
672 if (state == 0)
673 {
674 FREE (dfn);
675 /* remove backslashes quoting special characters in filenames. */
676 if (rl_filename_dequoting_function)
677 {
678 qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
679 dfn = (*rl_filename_dequoting_function) ((char *)text, qc);
680 }
681 else
682 dfn = savestring (text);
683 }
684
685 return (rl_filename_completion_function (dfn, state));
686 }
687
688 #define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
689 do { \
690 if (bmap & flag) \
691 { \
692 tlist = gen_matches_from_itemlist (it, text); \
693 if (tlist) \
694 { \
695 glist = strlist_append (glist, tlist); \
696 strlist_dispose (tlist); \
697 } \
698 } \
699 } while (0)
700
701 #define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
702 do { \
703 if (bmap & flag) \
704 { \
705 cmatches = rl_completion_matches (text, func); \
706 tlist = completions_to_stringlist (cmatches); \
707 glist = strlist_append (glist, tlist); \
708 strvec_dispose (cmatches); \
709 strlist_dispose (tlist); \
710 } \
711 } while (0)
712
713 /* Functions to generate lists of matches from the actions member of CS. */
714
715 static STRINGLIST *
716 gen_action_completions (cs, text)
717 COMPSPEC *cs;
718 const char *text;
719 {
720 STRINGLIST *ret, *tmatches;
721 char **cmatches; /* from rl_completion_matches ... */
722 unsigned long flags;
723
724 ret = tmatches = (STRINGLIST *)NULL;
725 flags = cs->actions;
726
727 GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches);
728 GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches);
729 GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches);
730 GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches);
731 GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches);
732 GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches);
733 GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches);
734 GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches);
735 GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches);
736 GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches);
737 GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches);
738 GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches);
739 GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches);
740 GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches);
741 GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches);
742 GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches);
743 GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches);
744
745 GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches);
746 GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
747 GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
748 GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
749 GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
750
751 /* And lastly, the special case for directories */
752 if (flags & CA_DIRECTORY)
753 {
754 rl_completion_mark_symlink_dirs = 1; /* override user preference */
755 cmatches = bash_directory_completion_matches (text);
756 tmatches = completions_to_stringlist (cmatches);
757 ret = strlist_append (ret, tmatches);
758 strvec_dispose (cmatches);
759 strlist_dispose (tmatches);
760 }
761
762 return ret;
763 }
764
765 /* Generate a list of matches for CS->globpat. Unresolved: should this use
766 TEXT as a match prefix, or just go without? Currently, the code does not
767 use TEXT, just globs CS->globpat and returns the results. If we do decide
768 to use TEXT, we should call quote_string_for_globbing before the call to
769 glob_filename. */
770 static STRINGLIST *
771 gen_globpat_matches (cs, text)
772 COMPSPEC *cs;
773 const char *text;
774 {
775 STRINGLIST *sl;
776
777 sl = strlist_create (0);
778 sl->list = glob_filename (cs->globpat, 0);
779 if (GLOB_FAILED (sl->list))
780 sl->list = (char **)NULL;
781 if (sl->list)
782 sl->list_len = sl->list_size = strvec_len (sl->list);
783 return sl;
784 }
785
786 /* Perform the shell word expansions on CS->words and return the results.
787 Again, this ignores TEXT. */
788 static STRINGLIST *
789 gen_wordlist_matches (cs, text)
790 COMPSPEC *cs;
791 const char *text;
792 {
793 WORD_LIST *l, *l2;
794 STRINGLIST *sl;
795 int nw, tlen;
796
797 if (cs->words == 0 || cs->words[0] == '\0')
798 return ((STRINGLIST *)NULL);
799
800 /* This used to be a simple expand_string(cs->words, 0), but that won't
801 do -- there's no way to split a simple list into individual words
802 that way, since the shell semantics say that word splitting is done
803 only on the results of expansion. */
804 l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, (int *)NULL, (int *)NULL);
805 if (l == 0)
806 return ((STRINGLIST *)NULL);
807 /* This will jump back to the top level if the expansion fails... */
808 l2 = expand_words_shellexp (l);
809 dispose_words (l);
810
811 nw = list_length (l2);
812 sl = strlist_create (nw + 1);
813 tlen = STRLEN (text);
814
815 for (nw = 0, l = l2; l; l = l->next)
816 {
817 if (tlen == 0 || STREQN (l->word->word, text, tlen))
818 sl->list[nw++] = STRDUP (l->word->word);
819 }
820 sl->list[sl->list_len = nw] = (char *)NULL;
821
822 return sl;
823 }
824
825 #ifdef ARRAY_VARS
826
827 static SHELL_VAR *
828 bind_comp_words (lwords)
829 WORD_LIST *lwords;
830 {
831 SHELL_VAR *v;
832
833 v = find_variable ("COMP_WORDS");
834 if (v == 0)
835 v = make_new_array_variable ("COMP_WORDS");
836 if (readonly_p (v))
837 VUNSETATTR (v, att_readonly);
838 if (array_p (v) == 0)
839 v = convert_var_to_array (v);
840 v = assign_array_var_from_word_list (v, lwords);
841 return v;
842 }
843 #endif /* ARRAY_VARS */
844
845 static void
846 bind_compfunc_variables (line, ind, lwords, cw, exported)
847 char *line;
848 int ind;
849 WORD_LIST *lwords;
850 int cw, exported;
851 {
852 char ibuf[INT_STRLEN_BOUND(int) + 1];
853 char *value;
854 SHELL_VAR *v;
855
856 /* Set the variables that the function expects while it executes. Maybe
857 these should be in the function environment (temporary_env). */
858 v = bind_variable ("COMP_LINE", line);
859 if (v && exported)
860 VSETATTR(v, att_exported);
861
862 value = inttostr (ind, ibuf, sizeof(ibuf));
863 v = bind_int_variable ("COMP_POINT", value);
864 if (v && exported)
865 VSETATTR(v, att_exported);
866
867 /* Since array variables can't be exported, we don't bother making the
868 array of words. */
869 if (exported == 0)
870 {
871 #ifdef ARRAY_VARS
872 v = bind_comp_words (lwords);
873 value = inttostr (cw, ibuf, sizeof(ibuf));
874 bind_int_variable ("COMP_CWORD", value);
875 #endif
876 }
877 else
878 array_needs_making = 1;
879 }
880
881 static void
882 unbind_compfunc_variables (exported)
883 int exported;
884 {
885 unbind_variable ("COMP_LINE");
886 unbind_variable ("COMP_POINT");
887 #ifdef ARRAY_VARS
888 unbind_variable ("COMP_WORDS");
889 unbind_variable ("COMP_CWORD");
890 #endif
891 if (exported)
892 array_needs_making = 1;
893 }
894
895 /* Build the list of words to pass to a function or external command
896 as arguments. When the function or command is invoked,
897
898 $0 == function or command being invoked
899 $1 == command name
900 $2 = word to be completed (possibly null)
901 $3 = previous word
902
903 Functions can access all of the words in the current command line
904 with the COMP_WORDS array. External commands cannot. */
905
906 static WORD_LIST *
907 build_arg_list (cmd, text, lwords, ind)
908 char *cmd;
909 const char *text;
910 WORD_LIST *lwords;
911 int ind;
912 {
913 WORD_LIST *ret, *cl, *l;
914 WORD_DESC *w;
915 int i;
916
917 ret = (WORD_LIST *)NULL;
918 w = make_word (cmd);
919 ret = make_word_list (w, (WORD_LIST *)NULL);
920
921 w = (lwords && lwords->word) ? copy_word (lwords->word) : make_word ("");
922 cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
923
924 w = make_word (text);
925 cl->next = make_word_list (w, (WORD_LIST *)NULL);
926 cl = cl->next;
927
928 /* Search lwords for current word */
929 for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
930 ;
931 w = (l && l->word) ? copy_word (l->word) : make_word ("");
932 cl->next = make_word_list (w, (WORD_LIST *)NULL);
933
934 return ret;
935 }
936
937 /* Build a command string with
938 $0 == cs->funcname (function to execute for completion list)
939 $1 == command name (command being completed)
940 $2 = word to be completed (possibly null)
941 $3 = previous word
942 and run in the current shell. The function should put its completion
943 list into the array variable COMPREPLY. We build a STRINGLIST
944 from the results and return it.
945
946 Since the shell function should return its list of matches in an array
947 variable, this does nothing if arrays are not compiled into the shell. */
948
949 static STRINGLIST *
950 gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
951 COMPSPEC *cs;
952 const char *text;
953 char *line;
954 int ind;
955 WORD_LIST *lwords;
956 int nw, cw;
957 {
958 char *funcname;
959 STRINGLIST *sl;
960 SHELL_VAR *f, *v;
961 WORD_LIST *cmdlist;
962 int fval;
963 #if defined (ARRAY_VARS)
964 ARRAY *a;
965 #endif
966
967 funcname = cs->funcname;
968 f = find_function (funcname);
969 if (f == 0)
970 {
971 internal_error ("completion: function `%s' not found", funcname);
972 rl_ding ();
973 rl_on_new_line ();
974 return ((STRINGLIST *)NULL);
975 }
976
977 #if !defined (ARRAY_VARS)
978 return ((STRINGLIST *)NULL);
979 #else
980
981 /* We pass cw - 1 because command_line_to_word_list returns indices that are
982 1-based, while bash arrays are 0-based. */
983 bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
984
985 cmdlist = build_arg_list (funcname, text, lwords, cw);
986
987 fval = execute_shell_function (f, cmdlist);
988
989 /* Now clean up and destroy everything. */
990 dispose_words (cmdlist);
991 unbind_compfunc_variables (0);
992
993 /* The list of completions is returned in the array variable COMPREPLY. */
994 v = find_variable ("COMPREPLY");
995 if (v == 0)
996 return ((STRINGLIST *)NULL);
997 if (array_p (v) == 0)
998 v = convert_var_to_array (v);
999
1000 a = array_cell (v);
1001 if (a == 0 || array_empty (a))
1002 sl = (STRINGLIST *)NULL;
1003 else
1004 {
1005 /* XXX - should we filter the list of completions so only those matching
1006 TEXT are returned? Right now, we do not. */
1007 sl = strlist_create (0);
1008 sl->list = array_to_argv (a);
1009 sl->list_len = sl->list_size = array_num_elements (a);
1010 }
1011
1012 /* XXX - should we unbind COMPREPLY here? */
1013 unbind_variable ("COMPREPLY");
1014
1015 return (sl);
1016 #endif
1017 }
1018
1019 /* Build a command string with
1020 $0 == cs->command (command to execute for completion list)
1021 $1 == command name (command being completed)
1022 $2 = word to be completed (possibly null)
1023 $3 = previous word
1024 and run in with command substitution. Parse the results, one word
1025 per line, with backslashes allowed to escape newlines. Build a
1026 STRINGLIST from the results and return it. */
1027
1028 static STRINGLIST *
1029 gen_command_matches (cs, text, line, ind, lwords, nw, cw)
1030 COMPSPEC *cs;
1031 const char *text;
1032 char *line;
1033 int ind;
1034 WORD_LIST *lwords;
1035 int nw, cw;
1036 {
1037 char *csbuf, *cscmd, *t;
1038 int cmdlen, cmdsize, n, ws, we;
1039 WORD_LIST *cmdlist, *cl;
1040 STRINGLIST *sl;
1041
1042 bind_compfunc_variables (line, ind, lwords, cw, 1);
1043 cmdlist = build_arg_list (cs->command, text, lwords, cw);
1044
1045 /* Estimate the size needed for the buffer. */
1046 n = strlen (cs->command);
1047 cmdsize = n + 1;
1048 for (cl = cmdlist->next; cl; cl = cl->next)
1049 cmdsize += STRLEN (cl->word->word) + 3;
1050 cmdsize += 2;
1051
1052 /* allocate the string for the command and fill it in. */
1053 cscmd = (char *)xmalloc (cmdsize + 1);
1054
1055 strcpy (cscmd, cs->command); /* $0 */
1056 cmdlen = n;
1057 cscmd[cmdlen++] = ' ';
1058 for (cl = cmdlist->next; cl; cl = cl->next) /* $1, $2, $3, ... */
1059 {
1060 t = sh_single_quote (cl->word->word ? cl->word->word : "");
1061 n = strlen (t);
1062 RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
1063 strcpy (cscmd + cmdlen, t);
1064 cmdlen += n;
1065 if (cl->next)
1066 cscmd[cmdlen++] = ' ';
1067 free (t);
1068 }
1069 cscmd[cmdlen] = '\0';
1070
1071 csbuf = command_substitute (cscmd, 0);
1072
1073 /* Now clean up and destroy everything. */
1074 dispose_words (cmdlist);
1075 free (cscmd);
1076 unbind_compfunc_variables (1);
1077
1078 if (csbuf == 0 || *csbuf == '\0')
1079 {
1080 FREE (csbuf);
1081 return ((STRINGLIST *)NULL);
1082 }
1083
1084 /* Now break CSBUF up at newlines, with backslash allowed to escape a
1085 newline, and put the individual words into a STRINGLIST. */
1086 sl = strlist_create (16);
1087 for (ws = 0; csbuf[ws]; )
1088 {
1089 we = ws;
1090 while (csbuf[we] && csbuf[we] != '\n')
1091 {
1092 if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
1093 we++;
1094 we++;
1095 }
1096 t = substring (csbuf, ws, we);
1097 if (sl->list_len >= sl->list_size - 1)
1098 strlist_resize (sl, sl->list_size + 16);
1099 sl->list[sl->list_len++] = t;
1100 while (csbuf[we] == '\n') we++;
1101 ws = we;
1102 }
1103 sl->list[sl->list_len] = (char *)NULL;
1104
1105 free (csbuf);
1106 return (sl);
1107 }
1108
1109 static WORD_LIST *
1110 command_line_to_word_list (line, llen, sentinel, nwp, cwp)
1111 char *line;
1112 int llen, sentinel, *nwp, *cwp;
1113 {
1114 WORD_LIST *ret;
1115 char *delims;
1116
1117 delims = "()<>;&| \t\n"; /* shell metacharacters break words */
1118 ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
1119 return (ret);
1120 }
1121
1122 /* Evaluate COMPSPEC *cs and return all matches for WORD. */
1123
1124 STRINGLIST *
1125 gen_compspec_completions (cs, cmd, word, start, end)
1126 COMPSPEC *cs;
1127 const char *cmd;
1128 const char *word;
1129 int start, end;
1130 {
1131 STRINGLIST *ret, *tmatches;
1132 char *line;
1133 int llen, nw, cw;
1134 WORD_LIST *lwords;
1135
1136 #ifdef DEBUG
1137 debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
1138 debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
1139 #endif
1140 ret = gen_action_completions (cs, word);
1141 #ifdef DEBUG
1142 if (ret && progcomp_debug)
1143 {
1144 debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
1145 strlist_print (ret, "\t");
1146 rl_on_new_line ();
1147 }
1148 #endif
1149
1150 /* Now we start generating completions based on the other members of CS. */
1151 if (cs->globpat)
1152 {
1153 tmatches = gen_globpat_matches (cs, word);
1154 if (tmatches)
1155 {
1156 #ifdef DEBUG
1157 if (progcomp_debug)
1158 {
1159 debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
1160 strlist_print (tmatches, "\t");
1161 rl_on_new_line ();
1162 }
1163 #endif
1164 ret = strlist_append (ret, tmatches);
1165 strlist_dispose (tmatches);
1166 rl_filename_completion_desired = 1;
1167 }
1168 }
1169
1170 if (cs->words)
1171 {
1172 tmatches = gen_wordlist_matches (cs, word);
1173 if (tmatches)
1174 {
1175 #ifdef DEBUG
1176 if (progcomp_debug)
1177 {
1178 debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
1179 strlist_print (tmatches, "\t");
1180 rl_on_new_line ();
1181 }
1182 #endif
1183 ret = strlist_append (ret, tmatches);
1184 strlist_dispose (tmatches);
1185 }
1186 }
1187
1188 lwords = (WORD_LIST *)NULL;
1189 line = (char *)NULL;
1190 if (cs->command || cs->funcname)
1191 {
1192 /* If we have a command or function to execute, we need to first break
1193 the command line into individual words, find the number of words,
1194 and find the word in the list containing the word to be completed. */
1195 line = substring (rl_line_buffer, start, end);
1196 llen = end - start;
1197
1198 #ifdef DEBUG
1199 debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
1200 line, llen, rl_point - start, &nw, &cw);
1201 #endif
1202 lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
1203 #ifdef DEBUG
1204 if (lwords == 0 && llen > 0)
1205 debug_printf ("ERROR: command_line_to_word_list returns NULL");
1206 else if (progcomp_debug)
1207 {
1208 debug_printf ("command_line_to_word_list -->");
1209 printf ("\t");
1210 print_word_list (lwords, "!");
1211 printf ("\n");
1212 fflush(stdout);
1213 rl_on_new_line ();
1214 }
1215 #endif
1216 }
1217
1218 if (cs->funcname)
1219 {
1220 tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1221 if (tmatches)
1222 {
1223 #ifdef DEBUG
1224 if (progcomp_debug)
1225 {
1226 debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1227 strlist_print (tmatches, "\t");
1228 rl_on_new_line ();
1229 }
1230 #endif
1231 ret = strlist_append (ret, tmatches);
1232 strlist_dispose (tmatches);
1233 }
1234 }
1235
1236 if (cs->command)
1237 {
1238 tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1239 if (tmatches)
1240 {
1241 #ifdef DEBUG
1242 if (progcomp_debug)
1243 {
1244 debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1245 strlist_print (tmatches, "\t");
1246 rl_on_new_line ();
1247 }
1248 #endif
1249 ret = strlist_append (ret, tmatches);
1250 strlist_dispose (tmatches);
1251 }
1252 }
1253
1254 if (cs->command || cs->funcname)
1255 {
1256 if (lwords)
1257 dispose_words (lwords);
1258 FREE (line);
1259 }
1260
1261 if (cs->filterpat)
1262 {
1263 tmatches = filter_stringlist (ret, cs->filterpat, word);
1264 #ifdef DEBUG
1265 if (progcomp_debug)
1266 {
1267 debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
1268 strlist_print (tmatches, "\t");
1269 rl_on_new_line ();
1270 }
1271 #endif
1272 if (ret && ret != tmatches)
1273 {
1274 FREE (ret->list);
1275 free (ret);
1276 }
1277 ret = tmatches;
1278 }
1279
1280 if (cs->prefix || cs->suffix)
1281 ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
1282
1283 /* If no matches have been generated and the user has specified that
1284 directory completion should be done as a default, call
1285 gen_action_completions again to generate a list of matching directory
1286 names. */
1287 if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
1288 {
1289 COMPSPEC *dummy;
1290
1291 dummy = compspec_create ();
1292 dummy->actions = CA_DIRECTORY;
1293 ret = gen_action_completions (dummy, word);
1294 compspec_dispose (dummy);
1295 }
1296
1297 return (ret);
1298 }
1299
1300 /* The driver function for the programmable completion code. Returns a list
1301 of matches for WORD, which is an argument to command CMD. START and END
1302 bound the command currently being completed in rl_line_buffer. */
1303 char **
1304 programmable_completions (cmd, word, start, end, foundp)
1305 const char *cmd;
1306 const char *word;
1307 int start, end, *foundp;
1308 {
1309 COMPSPEC *cs;
1310 STRINGLIST *ret;
1311 char **rmatches, *t;
1312
1313 /* We look at the basename of CMD if the full command does not have
1314 an associated COMPSPEC. */
1315 cs = progcomp_search (cmd);
1316 if (cs == 0)
1317 {
1318 t = strrchr (cmd, '/');
1319 if (t)
1320 cs = progcomp_search (++t);
1321 }
1322 if (cs == 0)
1323 {
1324 if (foundp)
1325 *foundp = 0;
1326 return ((char **)NULL);
1327 }
1328
1329 /* Signal the caller that we found a COMPSPEC for this command, and pass
1330 back any meta-options associated with the compspec. */
1331 if (foundp)
1332 *foundp = 1|cs->options;
1333
1334 ret = gen_compspec_completions (cs, cmd, word, start, end);
1335
1336 if (ret)
1337 {
1338 rmatches = ret->list;
1339 free (ret);
1340 }
1341 else
1342 rmatches = (char **)NULL;
1343
1344 return (rmatches);
1345 }
1346
1347 #endif /* PROGRAMMABLE_COMPLETION */