]> git.ipfire.org Git - thirdparty/bash.git/blob - pcomplete.c
Imported from ../bash-3.1.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-2005 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 *j;
517 JOB_STATE ws; /* wanted state */
518
519 if (jstate == 0)
520 ws = JRUNNING;
521 else if (jstate == 1)
522 ws = JSTOPPED;
523
524 sl = strlist_create (js.j_jobslots);
525 for (i = js.j_jobslots - 1; i >= 0; i--)
526 {
527 j = get_job_by_jid (i);
528 if (j == 0)
529 continue;
530 p = j->pipe;
531 if (jstate == -1 || JOBSTATE(i) == ws)
532 {
533 s = savestring (p->command);
534 t = strpbrk (s, " \t\n");
535 if (t)
536 *t = '\0';
537 sl->list[sl->list_len++] = s;
538 }
539 }
540 itp->slist = sl;
541 #else
542 itp->slist = (STRINGLIST *)NULL;
543 #endif
544 return 0;
545 }
546
547 static int
548 it_init_jobs (itp)
549 ITEMLIST *itp;
550 {
551 return (it_init_joblist (itp, -1));
552 }
553
554 static int
555 it_init_running (itp)
556 ITEMLIST *itp;
557 {
558 return (it_init_joblist (itp, 0));
559 }
560
561 static int
562 it_init_stopped (itp)
563 ITEMLIST *itp;
564 {
565 return (it_init_joblist (itp, 1));
566 }
567
568 static int
569 it_init_keywords (itp)
570 ITEMLIST *itp;
571 {
572 STRINGLIST *sl;
573 register int i, n;
574
575 for (n = 0; word_token_alist[n].word; n++)
576 ;
577 sl = strlist_create (n);
578 for (i = 0; i < n; i++)
579 sl->list[i] = word_token_alist[i].word;
580 sl->list[sl->list_len = i] = (char *)NULL;
581 itp->flags |= LIST_DONTFREEMEMBERS;
582 itp->slist = sl;
583 return 0;
584 }
585
586 static int
587 it_init_signals (itp)
588 ITEMLIST *itp;
589 {
590 STRINGLIST *sl;
591
592 sl = strlist_create (0);
593 sl->list = signal_names;
594 sl->list_len = strvec_len (sl->list);
595 itp->flags |= LIST_DONTFREE;
596 itp->slist = sl;
597 return 0;
598 }
599
600 static int
601 it_init_variables (itp)
602 ITEMLIST *itp;
603 {
604 init_itemlist_from_varlist (itp, all_visible_variables);
605 return 0;
606 }
607
608 static int
609 it_init_setopts (itp)
610 ITEMLIST *itp;
611 {
612 STRINGLIST *sl;
613
614 sl = strlist_create (0);
615 sl->list = get_minus_o_opts ();
616 sl->list_len = strvec_len (sl->list);
617 itp->slist = sl;
618 itp->flags |= LIST_DONTFREEMEMBERS;
619 return 0;
620 }
621
622 static int
623 it_init_shopts (itp)
624 ITEMLIST *itp;
625 {
626 STRINGLIST *sl;
627
628 sl = strlist_create (0);
629 sl->list = get_shopt_options ();
630 sl->list_len = strvec_len (sl->list);
631 itp->slist = sl;
632 itp->flags |= LIST_DONTFREEMEMBERS;
633 return 0;
634 }
635
636 /* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
637 as the list of possibilities. If the itemlist has been marked dirty or
638 it should be regenerated every time, destroy the old STRINGLIST and make a
639 new one before trying the match. TEXT is dequoted before attempting a
640 match. */
641 static STRINGLIST *
642 gen_matches_from_itemlist (itp, text)
643 ITEMLIST *itp;
644 const char *text;
645 {
646 STRINGLIST *ret, *sl;
647 int tlen, i, n;
648 char *ntxt;
649
650 if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
651 (itp->flags & LIST_INITIALIZED) == 0)
652 {
653 if (itp->flags & (LIST_DIRTY | LIST_DYNAMIC))
654 clean_itemlist (itp);
655 if ((itp->flags & LIST_INITIALIZED) == 0)
656 initialize_itemlist (itp);
657 }
658 if (itp->slist == 0)
659 return ((STRINGLIST *)NULL);
660 ret = strlist_create (itp->slist->list_len+1);
661 sl = itp->slist;
662
663 ntxt = bash_dequote_text (text);
664 tlen = STRLEN (ntxt);
665
666 for (i = n = 0; i < sl->list_len; i++)
667 {
668 if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
669 ret->list[n++] = STRDUP (sl->list[i]);
670 }
671 ret->list[ret->list_len = n] = (char *)NULL;
672
673 FREE (ntxt);
674 return ret;
675 }
676
677 /* A wrapper for rl_filename_completion_function that dequotes the filename
678 before attempting completions. */
679 static char *
680 pcomp_filename_completion_function (text, state)
681 const char *text;
682 int state;
683 {
684 static char *dfn; /* dequoted filename */
685 int qc;
686
687 if (state == 0)
688 {
689 FREE (dfn);
690 /* remove backslashes quoting special characters in filenames. */
691 if (rl_filename_dequoting_function)
692 {
693 #if 0
694 qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
695 #else
696 /* Use rl_completion_quote_character because any single or
697 double quotes have been removed by the time TEXT makes it
698 here, and we don't want to remove backslashes inside
699 quoted strings. */
700 qc = rl_dispatching ? rl_completion_quote_character : 0;
701 #endif
702 dfn = (*rl_filename_dequoting_function) ((char *)text, qc);
703 }
704 else
705 dfn = savestring (text);
706 }
707
708 return (rl_filename_completion_function (dfn, state));
709 }
710
711 #define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
712 do { \
713 if (bmap & flag) \
714 { \
715 tlist = gen_matches_from_itemlist (it, text); \
716 if (tlist) \
717 { \
718 glist = strlist_append (glist, tlist); \
719 strlist_dispose (tlist); \
720 } \
721 } \
722 } while (0)
723
724 #define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
725 do { \
726 if (bmap & flag) \
727 { \
728 cmatches = rl_completion_matches (text, func); \
729 tlist = completions_to_stringlist (cmatches); \
730 glist = strlist_append (glist, tlist); \
731 strvec_dispose (cmatches); \
732 strlist_dispose (tlist); \
733 } \
734 } while (0)
735
736 /* Functions to generate lists of matches from the actions member of CS. */
737
738 static STRINGLIST *
739 gen_action_completions (cs, text)
740 COMPSPEC *cs;
741 const char *text;
742 {
743 STRINGLIST *ret, *tmatches;
744 char **cmatches; /* from rl_completion_matches ... */
745 unsigned long flags;
746
747 ret = tmatches = (STRINGLIST *)NULL;
748 flags = cs->actions;
749
750 GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches);
751 GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches);
752 GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches);
753 GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches);
754 GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches);
755 GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches);
756 GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches);
757 GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches);
758 GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches);
759 GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches);
760 GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches);
761 GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches);
762 GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches);
763 GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches);
764 GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches);
765 GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches);
766 GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches);
767
768 GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches);
769 GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
770 GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
771 GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
772 GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
773
774 /* And lastly, the special case for directories */
775 if (flags & CA_DIRECTORY)
776 {
777 rl_completion_mark_symlink_dirs = 1; /* override user preference */
778 cmatches = bash_directory_completion_matches (text);
779 tmatches = completions_to_stringlist (cmatches);
780 ret = strlist_append (ret, tmatches);
781 strvec_dispose (cmatches);
782 strlist_dispose (tmatches);
783 }
784
785 return ret;
786 }
787
788 /* Generate a list of matches for CS->globpat. Unresolved: should this use
789 TEXT as a match prefix, or just go without? Currently, the code does not
790 use TEXT, just globs CS->globpat and returns the results. If we do decide
791 to use TEXT, we should call quote_string_for_globbing before the call to
792 glob_filename. */
793 static STRINGLIST *
794 gen_globpat_matches (cs, text)
795 COMPSPEC *cs;
796 const char *text;
797 {
798 STRINGLIST *sl;
799
800 sl = strlist_create (0);
801 sl->list = glob_filename (cs->globpat, 0);
802 if (GLOB_FAILED (sl->list))
803 sl->list = (char **)NULL;
804 if (sl->list)
805 sl->list_len = sl->list_size = strvec_len (sl->list);
806 return sl;
807 }
808
809 /* Perform the shell word expansions on CS->words and return the results.
810 Again, this ignores TEXT. */
811 static STRINGLIST *
812 gen_wordlist_matches (cs, text)
813 COMPSPEC *cs;
814 const char *text;
815 {
816 WORD_LIST *l, *l2;
817 STRINGLIST *sl;
818 int nw, tlen, qc;
819 char *ntxt; /* dequoted TEXT to use in comparisons */
820
821 if (cs->words == 0 || cs->words[0] == '\0')
822 return ((STRINGLIST *)NULL);
823
824 /* This used to be a simple expand_string(cs->words, 0), but that won't
825 do -- there's no way to split a simple list into individual words
826 that way, since the shell semantics say that word splitting is done
827 only on the results of expansion. */
828 l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, (int *)NULL, (int *)NULL);
829 if (l == 0)
830 return ((STRINGLIST *)NULL);
831 /* This will jump back to the top level if the expansion fails... */
832 l2 = expand_words_shellexp (l);
833 dispose_words (l);
834
835 nw = list_length (l2);
836 sl = strlist_create (nw + 1);
837
838 ntxt = bash_dequote_text (text);
839 tlen = STRLEN (ntxt);
840
841 for (nw = 0, l = l2; l; l = l->next)
842 {
843 if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
844 sl->list[nw++] = STRDUP (l->word->word);
845 }
846 sl->list[sl->list_len = nw] = (char *)NULL;
847
848 dispose_words (l2);
849 FREE (ntxt);
850 return sl;
851 }
852
853 #ifdef ARRAY_VARS
854
855 static SHELL_VAR *
856 bind_comp_words (lwords)
857 WORD_LIST *lwords;
858 {
859 SHELL_VAR *v;
860
861 v = find_variable ("COMP_WORDS");
862 if (v == 0)
863 v = make_new_array_variable ("COMP_WORDS");
864 if (readonly_p (v))
865 VUNSETATTR (v, att_readonly);
866 if (array_p (v) == 0)
867 v = convert_var_to_array (v);
868 v = assign_array_var_from_word_list (v, lwords, 0);
869
870 VUNSETATTR (v, att_invisible);
871 return v;
872 }
873 #endif /* ARRAY_VARS */
874
875 static void
876 bind_compfunc_variables (line, ind, lwords, cw, exported)
877 char *line;
878 int ind;
879 WORD_LIST *lwords;
880 int cw, exported;
881 {
882 char ibuf[INT_STRLEN_BOUND(int) + 1];
883 char *value;
884 SHELL_VAR *v;
885
886 /* Set the variables that the function expects while it executes. Maybe
887 these should be in the function environment (temporary_env). */
888 v = bind_variable ("COMP_LINE", line, 0);
889 if (v && exported)
890 VSETATTR(v, att_exported);
891
892 value = inttostr (ind, ibuf, sizeof(ibuf));
893 v = bind_int_variable ("COMP_POINT", value);
894 if (v && exported)
895 VSETATTR(v, att_exported);
896
897 /* Since array variables can't be exported, we don't bother making the
898 array of words. */
899 if (exported == 0)
900 {
901 #ifdef ARRAY_VARS
902 v = bind_comp_words (lwords);
903 value = inttostr (cw, ibuf, sizeof(ibuf));
904 bind_int_variable ("COMP_CWORD", value);
905 #endif
906 }
907 else
908 array_needs_making = 1;
909 }
910
911 static void
912 unbind_compfunc_variables (exported)
913 int exported;
914 {
915 unbind_variable ("COMP_LINE");
916 unbind_variable ("COMP_POINT");
917 #ifdef ARRAY_VARS
918 unbind_variable ("COMP_WORDS");
919 unbind_variable ("COMP_CWORD");
920 #endif
921 if (exported)
922 array_needs_making = 1;
923 }
924
925 /* Build the list of words to pass to a function or external command
926 as arguments. When the function or command is invoked,
927
928 $0 == function or command being invoked
929 $1 == command name
930 $2 = word to be completed (possibly null)
931 $3 = previous word
932
933 Functions can access all of the words in the current command line
934 with the COMP_WORDS array. External commands cannot. */
935
936 static WORD_LIST *
937 build_arg_list (cmd, text, lwords, ind)
938 char *cmd;
939 const char *text;
940 WORD_LIST *lwords;
941 int ind;
942 {
943 WORD_LIST *ret, *cl, *l;
944 WORD_DESC *w;
945 int i;
946
947 ret = (WORD_LIST *)NULL;
948 w = make_word (cmd);
949 ret = make_word_list (w, (WORD_LIST *)NULL);
950
951 w = (lwords && lwords->word) ? copy_word (lwords->word) : make_word ("");
952 cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
953
954 w = make_word (text);
955 cl->next = make_word_list (w, (WORD_LIST *)NULL);
956 cl = cl->next;
957
958 /* Search lwords for current word */
959 for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
960 ;
961 w = (l && l->word) ? copy_word (l->word) : make_word ("");
962 cl->next = make_word_list (w, (WORD_LIST *)NULL);
963
964 return ret;
965 }
966
967 /* Build a command string with
968 $0 == cs->funcname (function to execute for completion list)
969 $1 == command name (command being completed)
970 $2 = word to be completed (possibly null)
971 $3 = previous word
972 and run in the current shell. The function should put its completion
973 list into the array variable COMPREPLY. We build a STRINGLIST
974 from the results and return it.
975
976 Since the shell function should return its list of matches in an array
977 variable, this does nothing if arrays are not compiled into the shell. */
978
979 static STRINGLIST *
980 gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
981 COMPSPEC *cs;
982 const char *text;
983 char *line;
984 int ind;
985 WORD_LIST *lwords;
986 int nw, cw;
987 {
988 char *funcname;
989 STRINGLIST *sl;
990 SHELL_VAR *f, *v;
991 WORD_LIST *cmdlist;
992 int fval;
993 sh_parser_state_t ps;
994 #if defined (ARRAY_VARS)
995 ARRAY *a;
996 #endif
997
998 funcname = cs->funcname;
999 f = find_function (funcname);
1000 if (f == 0)
1001 {
1002 internal_error (_("completion: function `%s' not found"), funcname);
1003 rl_ding ();
1004 rl_on_new_line ();
1005 return ((STRINGLIST *)NULL);
1006 }
1007
1008 #if !defined (ARRAY_VARS)
1009 return ((STRINGLIST *)NULL);
1010 #else
1011
1012 /* We pass cw - 1 because command_line_to_word_list returns indices that are
1013 1-based, while bash arrays are 0-based. */
1014 bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
1015
1016 cmdlist = build_arg_list (funcname, text, lwords, cw);
1017
1018 save_parser_state (&ps);
1019 fval = execute_shell_function (f, cmdlist);
1020 restore_parser_state (&ps);
1021
1022 /* Now clean up and destroy everything. */
1023 dispose_words (cmdlist);
1024 unbind_compfunc_variables (0);
1025
1026 /* The list of completions is returned in the array variable COMPREPLY. */
1027 v = find_variable ("COMPREPLY");
1028 if (v == 0)
1029 return ((STRINGLIST *)NULL);
1030 if (array_p (v) == 0)
1031 v = convert_var_to_array (v);
1032
1033 VUNSETATTR (v, att_invisible);
1034
1035 a = array_cell (v);
1036 if (a == 0 || array_empty (a))
1037 sl = (STRINGLIST *)NULL;
1038 else
1039 {
1040 /* XXX - should we filter the list of completions so only those matching
1041 TEXT are returned? Right now, we do not. */
1042 sl = strlist_create (0);
1043 sl->list = array_to_argv (a);
1044 sl->list_len = sl->list_size = array_num_elements (a);
1045 }
1046
1047 /* XXX - should we unbind COMPREPLY here? */
1048 unbind_variable ("COMPREPLY");
1049
1050 return (sl);
1051 #endif
1052 }
1053
1054 /* Build a command string with
1055 $0 == cs->command (command to execute for completion list)
1056 $1 == command name (command being completed)
1057 $2 = word to be completed (possibly null)
1058 $3 = previous word
1059 and run in with command substitution. Parse the results, one word
1060 per line, with backslashes allowed to escape newlines. Build a
1061 STRINGLIST from the results and return it. */
1062
1063 static STRINGLIST *
1064 gen_command_matches (cs, text, line, ind, lwords, nw, cw)
1065 COMPSPEC *cs;
1066 const char *text;
1067 char *line;
1068 int ind;
1069 WORD_LIST *lwords;
1070 int nw, cw;
1071 {
1072 char *csbuf, *cscmd, *t;
1073 int cmdlen, cmdsize, n, ws, we;
1074 WORD_LIST *cmdlist, *cl;
1075 STRINGLIST *sl;
1076
1077 bind_compfunc_variables (line, ind, lwords, cw, 1);
1078 cmdlist = build_arg_list (cs->command, text, lwords, cw);
1079
1080 /* Estimate the size needed for the buffer. */
1081 n = strlen (cs->command);
1082 cmdsize = n + 1;
1083 for (cl = cmdlist->next; cl; cl = cl->next)
1084 cmdsize += STRLEN (cl->word->word) + 3;
1085 cmdsize += 2;
1086
1087 /* allocate the string for the command and fill it in. */
1088 cscmd = (char *)xmalloc (cmdsize + 1);
1089
1090 strcpy (cscmd, cs->command); /* $0 */
1091 cmdlen = n;
1092 cscmd[cmdlen++] = ' ';
1093 for (cl = cmdlist->next; cl; cl = cl->next) /* $1, $2, $3, ... */
1094 {
1095 t = sh_single_quote (cl->word->word ? cl->word->word : "");
1096 n = strlen (t);
1097 RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
1098 strcpy (cscmd + cmdlen, t);
1099 cmdlen += n;
1100 if (cl->next)
1101 cscmd[cmdlen++] = ' ';
1102 free (t);
1103 }
1104 cscmd[cmdlen] = '\0';
1105
1106 csbuf = command_substitute (cscmd, 0);
1107
1108 /* Now clean up and destroy everything. */
1109 dispose_words (cmdlist);
1110 free (cscmd);
1111 unbind_compfunc_variables (1);
1112
1113 if (csbuf == 0 || *csbuf == '\0')
1114 {
1115 FREE (csbuf);
1116 return ((STRINGLIST *)NULL);
1117 }
1118
1119 /* Now break CSBUF up at newlines, with backslash allowed to escape a
1120 newline, and put the individual words into a STRINGLIST. */
1121 sl = strlist_create (16);
1122 for (ws = 0; csbuf[ws]; )
1123 {
1124 we = ws;
1125 while (csbuf[we] && csbuf[we] != '\n')
1126 {
1127 if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
1128 we++;
1129 we++;
1130 }
1131 t = substring (csbuf, ws, we);
1132 if (sl->list_len >= sl->list_size - 1)
1133 strlist_resize (sl, sl->list_size + 16);
1134 sl->list[sl->list_len++] = t;
1135 while (csbuf[we] == '\n') we++;
1136 ws = we;
1137 }
1138 sl->list[sl->list_len] = (char *)NULL;
1139
1140 free (csbuf);
1141 return (sl);
1142 }
1143
1144 static WORD_LIST *
1145 command_line_to_word_list (line, llen, sentinel, nwp, cwp)
1146 char *line;
1147 int llen, sentinel, *nwp, *cwp;
1148 {
1149 WORD_LIST *ret;
1150 char *delims;
1151
1152 delims = "()<>;&| \t\n"; /* shell metacharacters break words */
1153 ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
1154 return (ret);
1155 }
1156
1157 /* Evaluate COMPSPEC *cs and return all matches for WORD. */
1158
1159 STRINGLIST *
1160 gen_compspec_completions (cs, cmd, word, start, end)
1161 COMPSPEC *cs;
1162 const char *cmd;
1163 const char *word;
1164 int start, end;
1165 {
1166 STRINGLIST *ret, *tmatches;
1167 char *line;
1168 int llen, nw, cw;
1169 WORD_LIST *lwords;
1170 COMPSPEC *tcs;
1171
1172 #ifdef DEBUG
1173 debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
1174 debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
1175 #endif
1176 ret = gen_action_completions (cs, word);
1177 #ifdef DEBUG
1178 if (ret && progcomp_debug)
1179 {
1180 debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
1181 strlist_print (ret, "\t");
1182 rl_on_new_line ();
1183 }
1184 #endif
1185
1186 /* Now we start generating completions based on the other members of CS. */
1187 if (cs->globpat)
1188 {
1189 tmatches = gen_globpat_matches (cs, word);
1190 if (tmatches)
1191 {
1192 #ifdef DEBUG
1193 if (progcomp_debug)
1194 {
1195 debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
1196 strlist_print (tmatches, "\t");
1197 rl_on_new_line ();
1198 }
1199 #endif
1200 ret = strlist_append (ret, tmatches);
1201 strlist_dispose (tmatches);
1202 rl_filename_completion_desired = 1;
1203 }
1204 }
1205
1206 if (cs->words)
1207 {
1208 tmatches = gen_wordlist_matches (cs, word);
1209 if (tmatches)
1210 {
1211 #ifdef DEBUG
1212 if (progcomp_debug)
1213 {
1214 debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
1215 strlist_print (tmatches, "\t");
1216 rl_on_new_line ();
1217 }
1218 #endif
1219 ret = strlist_append (ret, tmatches);
1220 strlist_dispose (tmatches);
1221 }
1222 }
1223
1224 lwords = (WORD_LIST *)NULL;
1225 line = (char *)NULL;
1226 if (cs->command || cs->funcname)
1227 {
1228 /* If we have a command or function to execute, we need to first break
1229 the command line into individual words, find the number of words,
1230 and find the word in the list containing the word to be completed. */
1231 line = substring (rl_line_buffer, start, end);
1232 llen = end - start;
1233
1234 #ifdef DEBUG
1235 debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
1236 line, llen, rl_point - start, &nw, &cw);
1237 #endif
1238 lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
1239 #ifdef DEBUG
1240 if (lwords == 0 && llen > 0)
1241 debug_printf ("ERROR: command_line_to_word_list returns NULL");
1242 else if (progcomp_debug)
1243 {
1244 debug_printf ("command_line_to_word_list -->");
1245 printf ("\t");
1246 print_word_list (lwords, "!");
1247 printf ("\n");
1248 fflush(stdout);
1249 rl_on_new_line ();
1250 }
1251 #endif
1252 }
1253
1254 if (cs->funcname)
1255 {
1256 tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1257 if (tmatches)
1258 {
1259 #ifdef DEBUG
1260 if (progcomp_debug)
1261 {
1262 debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1263 strlist_print (tmatches, "\t");
1264 rl_on_new_line ();
1265 }
1266 #endif
1267 ret = strlist_append (ret, tmatches);
1268 strlist_dispose (tmatches);
1269 }
1270 }
1271
1272 if (cs->command)
1273 {
1274 tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1275 if (tmatches)
1276 {
1277 #ifdef DEBUG
1278 if (progcomp_debug)
1279 {
1280 debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1281 strlist_print (tmatches, "\t");
1282 rl_on_new_line ();
1283 }
1284 #endif
1285 ret = strlist_append (ret, tmatches);
1286 strlist_dispose (tmatches);
1287 }
1288 }
1289
1290 if (cs->command || cs->funcname)
1291 {
1292 if (lwords)
1293 dispose_words (lwords);
1294 FREE (line);
1295 }
1296
1297 if (cs->filterpat)
1298 {
1299 tmatches = filter_stringlist (ret, cs->filterpat, word);
1300 #ifdef DEBUG
1301 if (progcomp_debug)
1302 {
1303 debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
1304 strlist_print (tmatches, "\t");
1305 rl_on_new_line ();
1306 }
1307 #endif
1308 if (ret && ret != tmatches)
1309 {
1310 FREE (ret->list);
1311 free (ret);
1312 }
1313 ret = tmatches;
1314 }
1315
1316 if (cs->prefix || cs->suffix)
1317 ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
1318
1319 /* If no matches have been generated and the user has specified that
1320 directory completion should be done as a default, call
1321 gen_action_completions again to generate a list of matching directory
1322 names. */
1323 if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
1324 {
1325 tcs = compspec_create ();
1326 tcs->actions = CA_DIRECTORY;
1327 ret = gen_action_completions (tcs, word);
1328 compspec_dispose (tcs);
1329 }
1330 else if (cs->options & COPT_PLUSDIRS)
1331 {
1332 tcs = compspec_create ();
1333 tcs->actions = CA_DIRECTORY;
1334 tmatches = gen_action_completions (tcs, word);
1335 ret = strlist_append (ret, tmatches);
1336 strlist_dispose (tmatches);
1337 compspec_dispose (tcs);
1338 }
1339
1340 return (ret);
1341 }
1342
1343 /* The driver function for the programmable completion code. Returns a list
1344 of matches for WORD, which is an argument to command CMD. START and END
1345 bound the command currently being completed in rl_line_buffer. */
1346 char **
1347 programmable_completions (cmd, word, start, end, foundp)
1348 const char *cmd;
1349 const char *word;
1350 int start, end, *foundp;
1351 {
1352 COMPSPEC *cs;
1353 STRINGLIST *ret;
1354 char **rmatches, *t;
1355
1356 /* We look at the basename of CMD if the full command does not have
1357 an associated COMPSPEC. */
1358 cs = progcomp_search (cmd);
1359 if (cs == 0)
1360 {
1361 t = strrchr (cmd, '/');
1362 if (t)
1363 cs = progcomp_search (++t);
1364 }
1365 if (cs == 0)
1366 {
1367 if (foundp)
1368 *foundp = 0;
1369 return ((char **)NULL);
1370 }
1371
1372 cs = compspec_copy (cs);
1373
1374 /* Signal the caller that we found a COMPSPEC for this command, and pass
1375 back any meta-options associated with the compspec. */
1376 if (foundp)
1377 *foundp = 1|cs->options;
1378
1379 ret = gen_compspec_completions (cs, cmd, word, start, end);
1380
1381 compspec_dispose (cs);
1382
1383 if (ret)
1384 {
1385 rmatches = ret->list;
1386 free (ret);
1387 }
1388 else
1389 rmatches = (char **)NULL;
1390
1391 return (rmatches);
1392 }
1393
1394 #endif /* PROGRAMMABLE_COMPLETION */