commit bash-20051123 snapshot
[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 *j;
517   JOB_STATE ws;         /* wanted state */
518
519   if (jstate == 0)
520     ws = JRUNNING;
521   else if (jstate == 1)
522     ws = JSTOPPED;
523
524   sl = strlist_create (js.j_jobslots);
525   for (i = js.j_jobslots - 1; i >= 0; i--)
526     {
527       j = get_job_by_jid (i);
528       if (j == 0)
529         continue;
530       p = j->pipe;
531       if (jstate == -1 || JOBSTATE(i) == ws)
532         {
533           s = savestring (p->command);
534           t = strpbrk (s, " \t\n");
535           if (t)
536             *t = '\0';
537           sl->list[sl->list_len++] = s;
538         }
539     }
540   itp->slist = sl;
541 #else
542   itp->slist = (STRINGLIST *)NULL;
543 #endif
544   return 0;
545 }
546
547 static int
548 it_init_jobs (itp)
549      ITEMLIST *itp;
550 {
551   return (it_init_joblist (itp, -1));
552 }
553
554 static int
555 it_init_running (itp)
556      ITEMLIST *itp;
557 {
558   return (it_init_joblist (itp, 0));
559 }
560
561 static int
562 it_init_stopped (itp)
563      ITEMLIST *itp;
564 {
565   return (it_init_joblist (itp, 1));
566 }
567
568 static int
569 it_init_keywords (itp)
570      ITEMLIST *itp;
571 {
572   STRINGLIST *sl;
573   register int i, n;
574
575   for (n = 0; word_token_alist[n].word; n++)
576     ;
577   sl = strlist_create (n);
578   for (i = 0; i < n; i++)
579     sl->list[i] = word_token_alist[i].word;
580   sl->list[sl->list_len = i] = (char *)NULL;
581   itp->flags |= LIST_DONTFREEMEMBERS;
582   itp->slist = sl;
583   return 0;
584 }
585
586 static int
587 it_init_signals (itp)
588      ITEMLIST *itp;
589 {
590   STRINGLIST *sl;
591
592   sl = strlist_create (0);
593   sl->list = signal_names;
594   sl->list_len = strvec_len (sl->list);
595   itp->flags |= LIST_DONTFREE;
596   itp->slist = sl;
597   return 0;
598 }
599
600 static int
601 it_init_variables (itp)
602      ITEMLIST *itp;
603 {
604   init_itemlist_from_varlist (itp, all_visible_variables);
605   return 0;
606 }
607
608 static int
609 it_init_setopts (itp)
610      ITEMLIST *itp;
611 {
612   STRINGLIST *sl;
613
614   sl = strlist_create (0);
615   sl->list = get_minus_o_opts ();
616   sl->list_len = strvec_len (sl->list);
617   itp->slist = sl;
618   itp->flags |= LIST_DONTFREEMEMBERS;
619   return 0;
620 }
621
622 static int
623 it_init_shopts (itp)
624      ITEMLIST *itp;
625 {
626   STRINGLIST *sl;
627
628   sl = strlist_create (0);
629   sl->list = get_shopt_options ();
630   sl->list_len = strvec_len (sl->list);
631   itp->slist = sl;
632   itp->flags |= LIST_DONTFREEMEMBERS;
633   return 0;
634 }
635
636 /* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
637    as the list of possibilities.  If the itemlist has been marked dirty or
638    it should be regenerated every time, destroy the old STRINGLIST and make a
639    new one before trying the match.  TEXT is dequoted before attempting a
640    match. */
641 static STRINGLIST *
642 gen_matches_from_itemlist (itp, text)
643      ITEMLIST *itp;
644      const char *text;
645 {
646   STRINGLIST *ret, *sl;
647   int tlen, i, n;
648   char *ntxt;
649
650   if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
651       (itp->flags & LIST_INITIALIZED) == 0)
652     {
653       if (itp->flags & (LIST_DIRTY | LIST_DYNAMIC))
654         clean_itemlist (itp);
655       if ((itp->flags & LIST_INITIALIZED) == 0)
656         initialize_itemlist (itp);
657     }
658   if (itp->slist == 0)
659     return ((STRINGLIST *)NULL);
660   ret = strlist_create (itp->slist->list_len+1);
661   sl = itp->slist;
662
663   ntxt = bash_dequote_text (text);
664   tlen = STRLEN (ntxt);
665
666   for (i = n = 0; i < sl->list_len; i++)
667     {
668       if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
669         ret->list[n++] = STRDUP (sl->list[i]);
670     }
671   ret->list[ret->list_len = n] = (char *)NULL;
672
673   FREE (ntxt);
674   return ret;
675 }
676
677 /* A wrapper for rl_filename_completion_function that dequotes the filename
678    before attempting completions. */
679 static char *
680 pcomp_filename_completion_function (text, state)
681      const char *text;
682      int state;
683 {
684   static char *dfn;     /* dequoted filename */
685   int qc;
686
687   if (state == 0)
688     {
689       FREE (dfn);
690       /* remove backslashes quoting special characters in filenames. */
691       if (rl_filename_dequoting_function)
692         {
693 #if 0
694           qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
695 #else
696           /* Use rl_completion_quote_character because any single or
697              double quotes have been removed by the time TEXT makes it
698              here, and we don't want to remove backslashes inside
699              quoted strings. */
700           qc = rl_dispatching ? rl_completion_quote_character : 0;
701 #endif
702           dfn = (*rl_filename_dequoting_function) ((char *)text, qc);
703         }
704       else
705         dfn = savestring (text);
706     }
707
708   return (rl_filename_completion_function (dfn, state));
709 }
710
711 #define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
712   do { \
713     if (bmap & flag) \
714       { \
715         tlist = gen_matches_from_itemlist (it, text); \
716         if (tlist) \
717           { \
718             glist = strlist_append (glist, tlist); \
719             strlist_dispose (tlist); \
720           } \
721       } \
722   } while (0)
723
724 #define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
725   do { \
726     if (bmap & flag) \
727       { \
728         cmatches = rl_completion_matches (text, func); \
729         tlist = completions_to_stringlist (cmatches); \
730         glist = strlist_append (glist, tlist); \
731         strvec_dispose (cmatches); \
732         strlist_dispose (tlist); \
733       } \
734   } while (0)
735
736 /* Functions to generate lists of matches from the actions member of CS. */
737
738 static STRINGLIST *
739 gen_action_completions (cs, text)
740      COMPSPEC *cs;
741      const char *text;
742 {
743   STRINGLIST *ret, *tmatches;
744   char **cmatches;      /* from rl_completion_matches ... */
745   unsigned long flags;
746
747   ret = tmatches = (STRINGLIST *)NULL;
748   flags = cs->actions;
749
750   GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches);
751   GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches);
752   GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches);
753   GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches);
754   GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches);
755   GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches);
756   GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches);
757   GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches);
758   GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches);
759   GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches);
760   GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches);
761   GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches);
762   GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches);
763   GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches);
764   GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches);
765   GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches);
766   GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches);
767
768   GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches);
769   GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
770   GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
771   GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
772   GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
773
774   /* And lastly, the special case for directories */
775   if (flags & CA_DIRECTORY)
776     {
777       rl_completion_mark_symlink_dirs = 1;      /* override user preference */
778       cmatches = bash_directory_completion_matches (text);
779       tmatches = completions_to_stringlist (cmatches);
780       ret = strlist_append (ret, tmatches);
781       strvec_dispose (cmatches);
782       strlist_dispose (tmatches);
783     }
784
785   return ret;
786 }
787
788 /* Generate a list of matches for CS->globpat.  Unresolved: should this use
789    TEXT as a match prefix, or just go without?  Currently, the code does not
790    use TEXT, just globs CS->globpat and returns the results.  If we do decide
791    to use TEXT, we should call quote_string_for_globbing before the call to
792    glob_filename. */
793 static STRINGLIST *
794 gen_globpat_matches (cs, text)
795       COMPSPEC *cs;
796       const char *text;
797 {
798   STRINGLIST *sl;
799
800   sl = strlist_create (0);
801   sl->list = glob_filename (cs->globpat, 0);
802   if (GLOB_FAILED (sl->list))
803     sl->list = (char **)NULL;
804   if (sl->list)
805     sl->list_len = sl->list_size = strvec_len (sl->list);
806   return sl;
807 }
808
809 /* Perform the shell word expansions on CS->words and return the results.
810    Again, this ignores TEXT. */
811 static STRINGLIST *
812 gen_wordlist_matches (cs, text)
813      COMPSPEC *cs;
814      const char *text;
815 {
816   WORD_LIST *l, *l2;
817   STRINGLIST *sl;
818   int nw, tlen, qc;
819   char *ntxt;           /* dequoted TEXT to use in comparisons */
820
821   if (cs->words == 0 || cs->words[0] == '\0')
822     return ((STRINGLIST *)NULL);
823
824   /* This used to be a simple expand_string(cs->words, 0), but that won't
825      do -- there's no way to split a simple list into individual words
826      that way, since the shell semantics say that word splitting is done
827      only on the results of expansion. */
828   l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, (int *)NULL, (int *)NULL);
829   if (l == 0)
830     return ((STRINGLIST *)NULL);
831   /* This will jump back to the top level if the expansion fails... */
832   l2 = expand_words_shellexp (l);
833   dispose_words (l);
834
835   nw = list_length (l2);
836   sl = strlist_create (nw + 1);
837
838   ntxt = bash_dequote_text (text);
839   tlen = STRLEN (ntxt);
840
841   for (nw = 0, l = l2; l; l = l->next)
842     {
843       if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
844         sl->list[nw++] = STRDUP (l->word->word);
845     }
846   sl->list[sl->list_len = nw] = (char *)NULL;
847
848   FREE (ntxt);
849   return sl;
850 }
851
852 #ifdef ARRAY_VARS
853
854 static SHELL_VAR *
855 bind_comp_words (lwords)
856      WORD_LIST *lwords;
857 {
858   SHELL_VAR *v;
859
860   v = find_variable ("COMP_WORDS");
861   if (v == 0)
862     v = make_new_array_variable ("COMP_WORDS");
863   if (readonly_p (v))
864     VUNSETATTR (v, att_readonly);
865   if (array_p (v) == 0)
866     v = convert_var_to_array (v);
867   v = assign_array_var_from_word_list (v, lwords, 0);
868
869   VUNSETATTR (v, att_invisible);
870   return v;
871 }
872 #endif /* ARRAY_VARS */
873
874 static void
875 bind_compfunc_variables (line, ind, lwords, cw, exported)
876      char *line;
877      int ind;
878      WORD_LIST *lwords;
879      int cw, exported;
880 {
881   char ibuf[INT_STRLEN_BOUND(int) + 1];
882   char *value;
883   SHELL_VAR *v;
884
885   /* Set the variables that the function expects while it executes.  Maybe
886      these should be in the function environment (temporary_env). */
887   v = bind_variable ("COMP_LINE", line, 0);
888   if (v && exported)
889     VSETATTR(v, att_exported);
890
891   value = inttostr (ind, ibuf, sizeof(ibuf));
892   v = bind_int_variable ("COMP_POINT", value);
893   if (v && exported)
894     VSETATTR(v, att_exported);
895
896   /* Since array variables can't be exported, we don't bother making the
897      array of words. */
898   if (exported == 0)
899     {
900 #ifdef ARRAY_VARS
901       v = bind_comp_words (lwords);
902       value = inttostr (cw, ibuf, sizeof(ibuf));
903       bind_int_variable ("COMP_CWORD", value);
904 #endif
905     }
906   else
907     array_needs_making = 1;
908 }
909
910 static void
911 unbind_compfunc_variables (exported)
912      int exported;
913 {
914   unbind_variable ("COMP_LINE");
915   unbind_variable ("COMP_POINT");
916 #ifdef ARRAY_VARS
917   unbind_variable ("COMP_WORDS");
918   unbind_variable ("COMP_CWORD");
919 #endif
920   if (exported)
921     array_needs_making = 1;
922 }
923
924 /* Build the list of words to pass to a function or external command
925    as arguments.  When the function or command is invoked,
926
927         $0 == function or command being invoked
928         $1 == command name
929         $2 = word to be completed (possibly null)
930         $3 = previous word
931
932    Functions can access all of the words in the current command line
933    with the COMP_WORDS array.  External commands cannot. */
934
935 static WORD_LIST *
936 build_arg_list (cmd, text, lwords, ind)
937      char *cmd;
938      const char *text;
939      WORD_LIST *lwords;
940      int ind;
941 {
942   WORD_LIST *ret, *cl, *l;
943   WORD_DESC *w;
944   int i;
945
946   ret = (WORD_LIST *)NULL;
947   w = make_word (cmd);
948   ret = make_word_list (w, (WORD_LIST *)NULL);
949
950   w = (lwords && lwords->word) ? copy_word (lwords->word) : make_word ("");
951   cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
952
953   w = make_word (text);
954   cl->next = make_word_list (w, (WORD_LIST *)NULL);
955   cl = cl->next;
956
957   /* Search lwords for current word */
958   for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
959     ;
960   w = (l && l->word) ? copy_word (l->word) : make_word ("");
961   cl->next = make_word_list (w, (WORD_LIST *)NULL);
962
963   return ret;
964 }
965
966 /* Build a command string with
967         $0 == cs->funcname      (function to execute for completion list)
968         $1 == command name      (command being completed)
969         $2 = word to be completed (possibly null)
970         $3 = previous word
971    and run in the current shell.  The function should put its completion
972    list into the array variable COMPREPLY.  We build a STRINGLIST
973    from the results and return it.
974
975    Since the shell function should return its list of matches in an array
976    variable, this does nothing if arrays are not compiled into the shell. */
977
978 static STRINGLIST *
979 gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
980      COMPSPEC *cs;
981      const char *text;
982      char *line;
983      int ind;
984      WORD_LIST *lwords;
985      int nw, cw;
986 {
987   char *funcname;
988   STRINGLIST *sl;
989   SHELL_VAR *f, *v;
990   WORD_LIST *cmdlist;
991   int fval;
992   sh_parser_state_t ps;
993 #if defined (ARRAY_VARS)
994   ARRAY *a;
995 #endif
996
997   funcname = cs->funcname;
998   f = find_function (funcname);
999   if (f == 0)
1000     {
1001       internal_error (_("completion: function `%s' not found"), funcname);
1002       rl_ding ();
1003       rl_on_new_line ();
1004       return ((STRINGLIST *)NULL);
1005     }
1006
1007 #if !defined (ARRAY_VARS)
1008   return ((STRINGLIST *)NULL);
1009 #else
1010
1011   /* We pass cw - 1 because command_line_to_word_list returns indices that are
1012      1-based, while bash arrays are 0-based. */
1013   bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
1014
1015   cmdlist = build_arg_list (funcname, text, lwords, cw);
1016
1017   save_parser_state (&ps);  
1018   fval = execute_shell_function (f, cmdlist);  
1019   restore_parser_state (&ps);
1020
1021   /* Now clean up and destroy everything. */
1022   dispose_words (cmdlist);
1023   unbind_compfunc_variables (0);
1024
1025   /* The list of completions is returned in the array variable COMPREPLY. */
1026   v = find_variable ("COMPREPLY");
1027   if (v == 0)
1028     return ((STRINGLIST *)NULL);
1029   if (array_p (v) == 0)
1030     v = convert_var_to_array (v);
1031
1032   VUNSETATTR (v, att_invisible);
1033
1034   a = array_cell (v);
1035   if (a == 0 || array_empty (a))
1036     sl = (STRINGLIST *)NULL;
1037   else
1038     {
1039       /* XXX - should we filter the list of completions so only those matching
1040          TEXT are returned?  Right now, we do not. */
1041       sl = strlist_create (0);
1042       sl->list = array_to_argv (a);
1043       sl->list_len = sl->list_size = array_num_elements (a);
1044     }
1045
1046   /* XXX - should we unbind COMPREPLY here? */
1047   unbind_variable ("COMPREPLY");
1048
1049   return (sl);
1050 #endif
1051 }
1052
1053 /* Build a command string with
1054         $0 == cs->command       (command to execute for completion list)
1055         $1 == command name      (command being completed)
1056         $2 = word to be completed (possibly null)
1057         $3 = previous word
1058    and run in with command substitution.  Parse the results, one word
1059    per line, with backslashes allowed to escape newlines.  Build a
1060    STRINGLIST from the results and return it. */
1061
1062 static STRINGLIST *
1063 gen_command_matches (cs, text, line, ind, lwords, nw, cw)
1064      COMPSPEC *cs;
1065      const char *text;
1066      char *line;
1067      int ind;
1068      WORD_LIST *lwords;
1069      int nw, cw;
1070 {
1071   char *csbuf, *cscmd, *t;
1072   int cmdlen, cmdsize, n, ws, we;
1073   WORD_LIST *cmdlist, *cl;
1074   STRINGLIST *sl;
1075
1076   bind_compfunc_variables (line, ind, lwords, cw, 1);
1077   cmdlist = build_arg_list (cs->command, text, lwords, cw);
1078
1079   /* Estimate the size needed for the buffer. */
1080   n = strlen (cs->command);
1081   cmdsize = n + 1;
1082   for (cl = cmdlist->next; cl; cl = cl->next)
1083     cmdsize += STRLEN (cl->word->word) + 3;
1084   cmdsize += 2;
1085
1086   /* allocate the string for the command and fill it in. */
1087   cscmd = (char *)xmalloc (cmdsize + 1);
1088
1089   strcpy (cscmd, cs->command);                  /* $0 */
1090   cmdlen = n;
1091   cscmd[cmdlen++] = ' ';
1092   for (cl = cmdlist->next; cl; cl = cl->next)   /* $1, $2, $3, ... */
1093     {
1094       t = sh_single_quote (cl->word->word ? cl->word->word : "");
1095       n = strlen (t);
1096       RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
1097       strcpy (cscmd + cmdlen, t);
1098       cmdlen += n;
1099       if (cl->next)
1100         cscmd[cmdlen++] = ' ';
1101       free (t);
1102     }
1103   cscmd[cmdlen] = '\0';
1104
1105   csbuf = command_substitute (cscmd, 0);
1106
1107   /* Now clean up and destroy everything. */
1108   dispose_words (cmdlist);
1109   free (cscmd);
1110   unbind_compfunc_variables (1);
1111
1112   if (csbuf == 0 || *csbuf == '\0')
1113     {
1114       FREE (csbuf);
1115       return ((STRINGLIST *)NULL);
1116     }
1117
1118   /* Now break CSBUF up at newlines, with backslash allowed to escape a
1119      newline, and put the individual words into a STRINGLIST. */
1120   sl = strlist_create (16);
1121   for (ws = 0; csbuf[ws]; )
1122     {
1123       we = ws;
1124       while (csbuf[we] && csbuf[we] != '\n')
1125         {
1126           if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
1127             we++;
1128           we++;
1129         }
1130       t = substring (csbuf, ws, we);
1131       if (sl->list_len >= sl->list_size - 1)
1132         strlist_resize (sl, sl->list_size + 16);
1133       sl->list[sl->list_len++] = t;
1134       while (csbuf[we] == '\n') we++;
1135       ws = we;
1136     }
1137   sl->list[sl->list_len] = (char *)NULL;
1138
1139   free (csbuf);
1140   return (sl);
1141 }
1142
1143 static WORD_LIST *
1144 command_line_to_word_list (line, llen, sentinel, nwp, cwp)
1145      char *line;
1146      int llen, sentinel, *nwp, *cwp;
1147 {
1148   WORD_LIST *ret;
1149   char *delims;
1150
1151   delims = "()<>;&| \t\n";      /* shell metacharacters break words */
1152   ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
1153   return (ret);
1154 }
1155
1156 /* Evaluate COMPSPEC *cs and return all matches for WORD. */
1157
1158 STRINGLIST *
1159 gen_compspec_completions (cs, cmd, word, start, end)
1160      COMPSPEC *cs;
1161      const char *cmd;
1162      const char *word;
1163      int start, end;
1164 {
1165   STRINGLIST *ret, *tmatches;
1166   char *line;
1167   int llen, nw, cw;
1168   WORD_LIST *lwords;
1169   COMPSPEC *tcs;
1170
1171 #ifdef DEBUG
1172   debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
1173   debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
1174 #endif
1175   ret = gen_action_completions (cs, word);
1176 #ifdef DEBUG
1177   if (ret && progcomp_debug)
1178     {
1179       debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
1180       strlist_print (ret, "\t");
1181       rl_on_new_line ();
1182     }
1183 #endif
1184
1185   /* Now we start generating completions based on the other members of CS. */
1186   if (cs->globpat)
1187     {
1188       tmatches = gen_globpat_matches (cs, word);
1189       if (tmatches)
1190         {
1191 #ifdef DEBUG
1192           if (progcomp_debug)
1193             {
1194               debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
1195               strlist_print (tmatches, "\t");
1196               rl_on_new_line ();
1197             }
1198 #endif
1199           ret = strlist_append (ret, tmatches);
1200           strlist_dispose (tmatches);
1201           rl_filename_completion_desired = 1;
1202         }
1203     }
1204
1205   if (cs->words)
1206     {
1207       tmatches = gen_wordlist_matches (cs, word);
1208       if (tmatches)
1209         {
1210 #ifdef DEBUG
1211           if (progcomp_debug)
1212             {
1213               debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
1214               strlist_print (tmatches, "\t");
1215               rl_on_new_line ();
1216             }
1217 #endif
1218           ret = strlist_append (ret, tmatches);
1219           strlist_dispose (tmatches);
1220         }
1221     }
1222
1223   lwords = (WORD_LIST *)NULL;
1224   line = (char *)NULL;
1225   if (cs->command || cs->funcname)
1226     {
1227       /* If we have a command or function to execute, we need to first break
1228          the command line into individual words, find the number of words,
1229          and find the word in the list containing the word to be completed. */
1230       line = substring (rl_line_buffer, start, end);
1231       llen = end - start;
1232
1233 #ifdef DEBUG
1234       debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
1235                 line, llen, rl_point - start, &nw, &cw);
1236 #endif
1237       lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
1238 #ifdef DEBUG
1239       if (lwords == 0 && llen > 0)
1240         debug_printf ("ERROR: command_line_to_word_list returns NULL");
1241       else if (progcomp_debug)
1242         {
1243           debug_printf ("command_line_to_word_list -->");
1244           printf ("\t");
1245           print_word_list (lwords, "!");
1246           printf ("\n");
1247           fflush(stdout);
1248           rl_on_new_line ();
1249         }
1250 #endif
1251     }
1252
1253   if (cs->funcname)
1254     {
1255       tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1256       if (tmatches)
1257         {
1258 #ifdef DEBUG
1259           if (progcomp_debug)
1260             {
1261               debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1262               strlist_print (tmatches, "\t");
1263               rl_on_new_line ();
1264             }
1265 #endif
1266           ret = strlist_append (ret, tmatches);
1267           strlist_dispose (tmatches);
1268         }
1269     }
1270
1271   if (cs->command)
1272     {
1273       tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1274       if (tmatches)
1275         {
1276 #ifdef DEBUG
1277           if (progcomp_debug)
1278             {
1279               debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
1280               strlist_print (tmatches, "\t");
1281               rl_on_new_line ();
1282             }
1283 #endif
1284           ret = strlist_append (ret, tmatches);
1285           strlist_dispose (tmatches);
1286         }
1287     }
1288
1289   if (cs->command || cs->funcname)
1290     {
1291       if (lwords)
1292         dispose_words (lwords);
1293       FREE (line);
1294     }
1295
1296   if (cs->filterpat)
1297     {
1298       tmatches = filter_stringlist (ret, cs->filterpat, word);
1299 #ifdef DEBUG
1300       if (progcomp_debug)
1301         {
1302           debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
1303           strlist_print (tmatches, "\t");
1304           rl_on_new_line ();
1305         }
1306 #endif
1307       if (ret && ret != tmatches)
1308         {
1309           FREE (ret->list);
1310           free (ret);
1311         }
1312       ret = tmatches;
1313     }
1314
1315   if (cs->prefix || cs->suffix)
1316     ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
1317
1318   /* If no matches have been generated and the user has specified that
1319       directory completion should be done as a default, call
1320       gen_action_completions again to generate a list of matching directory
1321       names. */
1322   if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
1323     {
1324       tcs = compspec_create ();
1325       tcs->actions = CA_DIRECTORY;
1326       ret = gen_action_completions (tcs, word);
1327       compspec_dispose (tcs);
1328     }
1329   else if (cs->options & COPT_PLUSDIRS)
1330     {
1331       tcs = compspec_create ();
1332       tcs->actions = CA_DIRECTORY;
1333       tmatches = gen_action_completions (tcs, word);
1334       ret = strlist_append (ret, tmatches);
1335       strlist_dispose (tmatches);
1336       compspec_dispose (tcs);
1337     }
1338
1339   return (ret);
1340 }
1341
1342 /* The driver function for the programmable completion code.  Returns a list
1343    of matches for WORD, which is an argument to command CMD.  START and END
1344    bound the command currently being completed in rl_line_buffer. */
1345 char **
1346 programmable_completions (cmd, word, start, end, foundp)
1347      const char *cmd;
1348      const char *word;
1349      int start, end, *foundp;
1350 {
1351   COMPSPEC *cs;
1352   STRINGLIST *ret;
1353   char **rmatches, *t;
1354
1355   /* We look at the basename of CMD if the full command does not have
1356      an associated COMPSPEC. */
1357   cs = progcomp_search (cmd);
1358   if (cs == 0)
1359     {
1360       t = strrchr (cmd, '/');
1361       if (t)
1362         cs = progcomp_search (++t);
1363     }
1364   if (cs == 0)
1365     {
1366       if (foundp)
1367         *foundp = 0;
1368       return ((char **)NULL);
1369     }
1370
1371   cs = compspec_copy (cs);
1372
1373   /* Signal the caller that we found a COMPSPEC for this command, and pass
1374      back any meta-options associated with the compspec. */
1375   if (foundp)
1376     *foundp = 1|cs->options;
1377
1378   ret = gen_compspec_completions (cs, cmd, word, start, end);
1379
1380   compspec_dispose (cs);
1381
1382   if (ret)
1383     {
1384       rmatches = ret->list;
1385       free (ret);
1386     }
1387   else
1388     rmatches = (char **)NULL;
1389
1390   return (rmatches);
1391 }
1392
1393 #endif /* PROGRAMMABLE_COMPLETION */