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