17d37d51ba07213843d7358994664415e45ee67f
[platform/upstream/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 */