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