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