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