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