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