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