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