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