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