7f5ac54c99de8debd2716b5b105699d197af10d3
[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   return v;
867 }
868 #endif /* ARRAY_VARS */
869
870 static void
871 bind_compfunc_variables (line, ind, lwords, cw, exported)
872      char *line;
873      int ind;
874      WORD_LIST *lwords;
875      int cw, exported;
876 {
877   char ibuf[INT_STRLEN_BOUND(int) + 1];
878   char *value;
879   SHELL_VAR *v;
880
881   /* Set the variables that the function expects while it executes.  Maybe
882      these should be in the function environment (temporary_env). */
883   v = bind_variable ("COMP_LINE", line);
884   if (v && exported)
885     VSETATTR(v, att_exported);
886
887   value = inttostr (ind, ibuf, sizeof(ibuf));
888   v = bind_int_variable ("COMP_POINT", value);
889   if (v && exported)
890     VSETATTR(v, att_exported);
891
892   /* Since array variables can't be exported, we don't bother making the
893      array of words. */
894   if (exported == 0)
895     {
896 #ifdef ARRAY_VARS
897       v = bind_comp_words (lwords);
898       value = inttostr (cw, ibuf, sizeof(ibuf));
899       bind_int_variable ("COMP_CWORD", value);
900 #endif
901     }
902   else
903     array_needs_making = 1;
904 }
905
906 static void
907 unbind_compfunc_variables (exported)
908      int exported;
909 {
910   unbind_variable ("COMP_LINE");
911   unbind_variable ("COMP_POINT");
912 #ifdef ARRAY_VARS
913   unbind_variable ("COMP_WORDS");
914   unbind_variable ("COMP_CWORD");
915 #endif
916   if (exported)
917     array_needs_making = 1;
918 }
919
920 /* Build the list of words to pass to a function or external command
921    as arguments.  When the function or command is invoked,
922
923         $0 == function or command being invoked
924         $1 == command name
925         $2 = word to be completed (possibly null)
926         $3 = previous word
927
928    Functions can access all of the words in the current command line
929    with the COMP_WORDS array.  External commands cannot. */
930
931 static WORD_LIST *
932 build_arg_list (cmd, text, lwords, ind)
933      char *cmd;
934      const char *text;
935      WORD_LIST *lwords;
936      int ind;
937 {
938   WORD_LIST *ret, *cl, *l;
939   WORD_DESC *w;
940   int i;
941
942   ret = (WORD_LIST *)NULL;
943   w = make_word (cmd);
944   ret = make_word_list (w, (WORD_LIST *)NULL);
945
946   w = (lwords && lwords->word) ? copy_word (lwords->word) : make_word ("");
947   cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
948
949   w = make_word (text);
950   cl->next = make_word_list (w, (WORD_LIST *)NULL);
951   cl = cl->next;
952
953   /* Search lwords for current word */
954   for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
955     ;
956   w = (l && l->word) ? copy_word (l->word) : make_word ("");
957   cl->next = make_word_list (w, (WORD_LIST *)NULL);
958
959   return ret;
960 }
961
962 /* Build a command string with
963         $0 == cs->funcname      (function to execute for completion list)
964         $1 == command name      (command being completed)
965         $2 = word to be completed (possibly null)
966         $3 = previous word
967    and run in the current shell.  The function should put its completion
968    list into the array variable COMPREPLY.  We build a STRINGLIST
969    from the results and return it.
970
971    Since the shell function should return its list of matches in an array
972    variable, this does nothing if arrays are not compiled into the shell. */
973
974 static STRINGLIST *
975 gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
976      COMPSPEC *cs;
977      const char *text;
978      char *line;
979      int ind;
980      WORD_LIST *lwords;
981      int nw, cw;
982 {
983   char *funcname;
984   STRINGLIST *sl;
985   SHELL_VAR *f, *v;
986   WORD_LIST *cmdlist;
987   int fval;
988 #if defined (ARRAY_VARS)
989   ARRAY *a;
990 #endif
991
992   funcname = cs->funcname;
993   f = find_function (funcname);
994   if (f == 0)
995     {
996       internal_error (_("completion: function `%s' not found"), funcname);
997       rl_ding ();
998       rl_on_new_line ();
999       return ((STRINGLIST *)NULL);
1000     }
1001
1002 #if !defined (ARRAY_VARS)
1003   return ((STRINGLIST *)NULL);
1004 #else
1005
1006   /* We pass cw - 1 because command_line_to_word_list returns indices that are
1007      1-based, while bash arrays are 0-based. */
1008   bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
1009
1010   cmdlist = build_arg_list (funcname, text, lwords, cw);
1011   
1012   fval = execute_shell_function (f, cmdlist);  
1013
1014   /* Now clean up and destroy everything. */
1015   dispose_words (cmdlist);
1016   unbind_compfunc_variables (0);
1017
1018   /* The list of completions is returned in the array variable COMPREPLY. */
1019   v = find_variable ("COMPREPLY");
1020   if (v == 0)
1021     return ((STRINGLIST *)NULL);
1022   if (array_p (v) == 0)
1023     v = convert_var_to_array (v);
1024
1025   a = array_cell (v);
1026   if (a == 0 || array_empty (a))
1027     sl = (STRINGLIST *)NULL;
1028   else
1029     {
1030       /* XXX - should we filter the list of completions so only those matching
1031          TEXT are returned?  Right now, we do not. */
1032       sl = strlist_create (0);
1033       sl->list = array_to_argv (a);
1034       sl->list_len = sl->list_size = array_num_elements (a);
1035     }
1036
1037   /* XXX - should we unbind COMPREPLY here? */
1038   unbind_variable ("COMPREPLY");
1039
1040   return (sl);
1041 #endif
1042 }
1043
1044 /* Build a command string with
1045         $0 == cs->command       (command to execute for completion list)
1046         $1 == command name      (command being completed)
1047         $2 = word to be completed (possibly null)
1048         $3 = previous word
1049    and run in with command substitution.  Parse the results, one word
1050    per line, with backslashes allowed to escape newlines.  Build a
1051    STRINGLIST from the results and return it. */
1052
1053 static STRINGLIST *
1054 gen_command_matches (cs, text, line, ind, lwords, nw, cw)
1055      COMPSPEC *cs;
1056      const char *text;
1057      char *line;
1058      int ind;
1059      WORD_LIST *lwords;
1060      int nw, cw;
1061 {
1062   char *csbuf, *cscmd, *t;
1063   int cmdlen, cmdsize, n, ws, we;
1064   WORD_LIST *cmdlist, *cl;
1065   STRINGLIST *sl;
1066
1067   bind_compfunc_variables (line, ind, lwords, cw, 1);
1068   cmdlist = build_arg_list (cs->command, text, lwords, cw);
1069
1070   /* Estimate the size needed for the buffer. */
1071   n = strlen (cs->command);
1072   cmdsize = n + 1;
1073   for (cl = cmdlist->next; cl; cl = cl->next)
1074     cmdsize += STRLEN (cl->word->word) + 3;
1075   cmdsize += 2;
1076
1077   /* allocate the string for the command and fill it in. */
1078   cscmd = (char *)xmalloc (cmdsize + 1);
1079
1080   strcpy (cscmd, cs->command);                  /* $0 */
1081   cmdlen = n;
1082   cscmd[cmdlen++] = ' ';
1083   for (cl = cmdlist->next; cl; cl = cl->next)   /* $1, $2, $3, ... */
1084     {
1085       t = sh_single_quote (cl->word->word ? cl->word->word : "");
1086       n = strlen (t);
1087       RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
1088       strcpy (cscmd + cmdlen, t);
1089       cmdlen += n;
1090       if (cl->next)
1091         cscmd[cmdlen++] = ' ';
1092       free (t);
1093     }
1094   cscmd[cmdlen] = '\0';
1095
1096   csbuf = command_substitute (cscmd, 0);
1097
1098   /* Now clean up and destroy everything. */
1099   dispose_words (cmdlist);
1100   free (cscmd);
1101   unbind_compfunc_variables (1);
1102
1103   if (csbuf == 0 || *csbuf == '\0')
1104     {
1105       FREE (csbuf);
1106       return ((STRINGLIST *)NULL);
1107     }
1108
1109   /* Now break CSBUF up at newlines, with backslash allowed to escape a
1110      newline, and put the individual words into a STRINGLIST. */
1111   sl = strlist_create (16);
1112   for (ws = 0; csbuf[ws]; )
1113     {
1114       we = ws;
1115       while (csbuf[we] && csbuf[we] != '\n')
1116         {
1117           if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
1118             we++;
1119           we++;
1120         }
1121       t = substring (csbuf, ws, we);
1122       if (sl->list_len >= sl->list_size - 1)
1123         strlist_resize (sl, sl->list_size + 16);
1124       sl->list[sl->list_len++] = t;
1125       while (csbuf[we] == '\n') we++;
1126       ws = we;
1127     }
1128   sl->list[sl->list_len] = (char *)NULL;
1129
1130   free (csbuf);
1131   return (sl);
1132 }
1133
1134 static WORD_LIST *
1135 command_line_to_word_list (line, llen, sentinel, nwp, cwp)
1136      char *line;
1137      int llen, sentinel, *nwp, *cwp;
1138 {
1139   WORD_LIST *ret;
1140   char *delims;
1141
1142   delims = "()<>;&| \t\n";      /* shell metacharacters break words */
1143   ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
1144   return (ret);
1145 }
1146
1147 /* Evaluate COMPSPEC *cs and return all matches for WORD. */
1148
1149 STRINGLIST *
1150 gen_compspec_completions (cs, cmd, word, start, end)
1151      COMPSPEC *cs;
1152      const char *cmd;
1153      const char *word;
1154      int start, end;
1155 {
1156   STRINGLIST *ret, *tmatches;
1157   char *line;
1158   int llen, nw, cw;
1159   WORD_LIST *lwords;
1160   COMPSPEC *tcs;
1161
1162 #ifdef DEBUG
1163   debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
1164   debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
1165 #endif
1166   ret = gen_action_completions (cs, word);
1167 #ifdef DEBUG
1168   if (ret && progcomp_debug)
1169     {
1170       debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
1171       strlist_print (ret, "\t");
1172       rl_on_new_line ();
1173     }
1174 #endif
1175
1176   /* Now we start generating completions based on the other members of CS. */
1177   if (cs->globpat)
1178     {
1179       tmatches = gen_globpat_matches (cs, word);
1180       if (tmatches)
1181         {
1182 #ifdef DEBUG
1183           if (progcomp_debug)
1184             {
1185               debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
1186               strlist_print (tmatches, "\t");
1187               rl_on_new_line ();
1188             }
1189 #endif
1190           ret = strlist_append (ret, tmatches);
1191           strlist_dispose (tmatches);
1192           rl_filename_completion_desired = 1;
1193         }
1194     }
1195
1196   if (cs->words)
1197     {
1198       tmatches = gen_wordlist_matches (cs, word);
1199       if (tmatches)
1200         {
1201 #ifdef DEBUG
1202           if (progcomp_debug)
1203             {
1204               debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
1205               strlist_print (tmatches, "\t");
1206               rl_on_new_line ();
1207             }
1208 #endif
1209           ret = strlist_append (ret, tmatches);
1210           strlist_dispose (tmatches);
1211         }
1212     }
1213
1214   lwords = (WORD_LIST *)NULL;
1215   line = (char *)NULL;
1216   if (cs->command || cs->funcname)
1217     {
1218       /* If we have a command or function to execute, we need to first break
1219          the command line into individual words, find the number of words,
1220          and find the word in the list containing the word to be completed. */
1221       line = substring (rl_line_buffer, start, end);
1222       llen = end - start;
1223
1224 #ifdef DEBUG
1225       debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
1226                 line, llen, rl_point - start, &nw, &cw);
1227 #endif
1228       lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
1229 #ifdef DEBUG
1230       if (lwords == 0 && llen > 0)
1231         debug_printf ("ERROR: command_line_to_word_list returns NULL");
1232       else if (progcomp_debug)
1233         {
1234           debug_printf ("command_line_to_word_list -->");
1235           printf ("\t");
1236           print_word_list (lwords, "!");
1237           printf ("\n");
1238           fflush(stdout);
1239           rl_on_new_line ();
1240         }
1241 #endif
1242     }
1243
1244   if (cs->funcname)
1245     {
1246       tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1247       if (tmatches)
1248         {
1249 #ifdef DEBUG
1250           if (progcomp_debug)
1251             {
1252               debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1253               strlist_print (tmatches, "\t");
1254               rl_on_new_line ();
1255             }
1256 #endif
1257           ret = strlist_append (ret, tmatches);
1258           strlist_dispose (tmatches);
1259         }
1260     }
1261
1262   if (cs->command)
1263     {
1264       tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1265       if (tmatches)
1266         {
1267 #ifdef DEBUG
1268           if (progcomp_debug)
1269             {
1270               debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1271               strlist_print (tmatches, "\t");
1272               rl_on_new_line ();
1273             }
1274 #endif
1275           ret = strlist_append (ret, tmatches);
1276           strlist_dispose (tmatches);
1277         }
1278     }
1279
1280   if (cs->command || cs->funcname)
1281     {
1282       if (lwords)
1283         dispose_words (lwords);
1284       FREE (line);
1285     }
1286
1287   if (cs->filterpat)
1288     {
1289       tmatches = filter_stringlist (ret, cs->filterpat, word);
1290 #ifdef DEBUG
1291       if (progcomp_debug)
1292         {
1293           debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
1294           strlist_print (tmatches, "\t");
1295           rl_on_new_line ();
1296         }
1297 #endif
1298       if (ret && ret != tmatches)
1299         {
1300           FREE (ret->list);
1301           free (ret);
1302         }
1303       ret = tmatches;
1304     }
1305
1306   if (cs->prefix || cs->suffix)
1307     ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
1308
1309   /* If no matches have been generated and the user has specified that
1310       directory completion should be done as a default, call
1311       gen_action_completions again to generate a list of matching directory
1312       names. */
1313   if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
1314     {
1315       tcs = compspec_create ();
1316       tcs->actions = CA_DIRECTORY;
1317       ret = gen_action_completions (tcs, word);
1318       compspec_dispose (tcs);
1319     }
1320   else if (cs->options & COPT_PLUSDIRS)
1321     {
1322       tcs = compspec_create ();
1323       tcs->actions = CA_DIRECTORY;
1324       tmatches = gen_action_completions (tcs, word);
1325       ret = strlist_append (ret, tmatches);
1326       strlist_dispose (tmatches);
1327       compspec_dispose (tcs);
1328     }
1329
1330   return (ret);
1331 }
1332
1333 /* The driver function for the programmable completion code.  Returns a list
1334    of matches for WORD, which is an argument to command CMD.  START and END
1335    bound the command currently being completed in rl_line_buffer. */
1336 char **
1337 programmable_completions (cmd, word, start, end, foundp)
1338      const char *cmd;
1339      const char *word;
1340      int start, end, *foundp;
1341 {
1342   COMPSPEC *cs;
1343   STRINGLIST *ret;
1344   char **rmatches, *t;
1345
1346   /* We look at the basename of CMD if the full command does not have
1347      an associated COMPSPEC. */
1348   cs = progcomp_search (cmd);
1349   if (cs == 0)
1350     {
1351       t = strrchr (cmd, '/');
1352       if (t)
1353         cs = progcomp_search (++t);
1354     }
1355   if (cs == 0)
1356     {
1357       if (foundp)
1358         *foundp = 0;
1359       return ((char **)NULL);
1360     }
1361
1362   cs = compspec_copy (cs);
1363
1364   /* Signal the caller that we found a COMPSPEC for this command, and pass
1365      back any meta-options associated with the compspec. */
1366   if (foundp)
1367     *foundp = 1|cs->options;
1368
1369   ret = gen_compspec_completions (cs, cmd, word, start, end);
1370
1371   compspec_dispose (cs);
1372
1373   if (ret)
1374     {
1375       rmatches = ret->list;
1376       free (ret);
1377     }
1378   else
1379     rmatches = (char **)NULL;
1380
1381   return (rmatches);
1382 }
1383
1384 #endif /* PROGRAMMABLE_COMPLETION */