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