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