blob: 70cbc98a0accd5bf7c2875ac3e17d1ef722ad610 [file] [log] [blame]
Jari Aalto31859422009-01-12 13:36:28 +00001/* pcomplete.c - functions to generate lists of matches for programmable completion. */
Jari Aaltobb706242000-03-17 21:46:59 +00002
Chet Rameyac50fba2014-02-26 09:36:43 -05003/* Copyright (C) 1999-2012 Free Software Foundation, Inc.
Jari Aaltobb706242000-03-17 21:46:59 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 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.
Jari Aaltobb706242000-03-17 21:46:59 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 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.
Jari Aaltobb706242000-03-17 21:46:59 +000016
Jari Aalto31859422009-01-12 13:36:28 +000017 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*/
Jari Aaltobb706242000-03-17 21:46:59 +000020
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
Jari Aalto7117c2d2002-07-17 14:10:11 +000037# include <varargs.h>
Jari Aaltobb706242000-03-17 21:46:59 +000038#endif
39
Chet Rameyac50fba2014-02-26 09:36:43 -050040#include <sys/time.h>
41
Jari Aaltobb706242000-03-17 21:46:59 +000042#include <stdio.h>
43#include "bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000044#include "bashintl.h"
Jari Aaltobb706242000-03-17 21:46:59 +000045
46#include "shell.h"
47#include "pcomplete.h"
48#include "alias.h"
49#include "bashline.h"
Jari Aaltof73dda02001-11-13 17:56:06 +000050#include "execute_cmd.h"
Jari Aaltobb706242000-03-17 21:46:59 +000051#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
Chet Rameyac50fba2014-02-26 09:36:43 -050061#include "shmbutil.h"
62
Jari Aaltobb706242000-03-17 21:46:59 +000063#include "builtins.h"
64#include "builtins/common.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050065#include "builtins/builtext.h"
Jari Aaltobb706242000-03-17 21:46:59 +000066
67#include <glob/glob.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000068#include <glob/strmatch.h>
Jari Aaltobb706242000-03-17 21:46:59 +000069
70#include <readline/rlconf.h>
71#include <readline/readline.h>
72#include <readline/history.h>
73
Chet Ramey00018032011-11-21 20:51:19 -050074#define PCOMP_RETRYFAIL 256
75
Jari Aaltobb706242000-03-17 21:46:59 +000076#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
Jari Aaltobb706242000-03-17 21:46:59 +000087extern int array_needs_making;
88extern STRING_INT_ALIST word_token_alist[];
89extern char *signal_names[];
Chet Rameyac50fba2014-02-26 09:36:43 -050090extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
Jari Aaltobb706242000-03-17 21:46:59 +000091
Jari Aalto7117c2d2002-07-17 14:10:11 +000092#if defined (DEBUG)
93#if defined (PREFER_STDARG)
Jari Aaltof73dda02001-11-13 17:56:06 +000094static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
95#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +000096#endif /* DEBUG */
Jari Aaltof73dda02001-11-13 17:56:06 +000097
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 *));
Chet Rameyac50fba2014-02-26 09:36:43 -0500108static int it_init_helptopics __P((ITEMLIST *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000109static 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 *,
Chet Rameyac50fba2014-02-26 09:36:43 -0500129 const char *,
Jari Aaltof73dda02001-11-13 17:56:06 +0000130 char *, int, WORD_LIST *,
Chet Ramey00018032011-11-21 20:51:19 -0500131 int, int, int *));
Chet Rameyac50fba2014-02-26 09:36:43 -0500132static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *,
133 const char *,
134 char *, int, WORD_LIST *,
135 int, int));
Jari Aaltof73dda02001-11-13 17:56:06 +0000136
Chet Ramey00018032011-11-21 20:51:19 -0500137static STRINGLIST *gen_progcomp_completions __P((const char *, const char *,
138 const char *,
139 int, int, int *, int *,
140 COMPSPEC **));
141
Jari Aaltof73dda02001-11-13 17:56:06 +0000142static 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));
Chet Rameyac50fba2014-02-26 09:36:43 -0500149static WORD_LIST *build_arg_list __P((char *, const char *, const char *, WORD_LIST *, int));
Jari Aaltof73dda02001-11-13 17:56:06 +0000150static WORD_LIST *command_line_to_word_list __P((char *, int, int, int *, int *));
Jari Aaltobb706242000-03-17 21:46:59 +0000151
Jari Aalto7117c2d2002-07-17 14:10:11 +0000152#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +0000153static int progcomp_debug = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000154#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000155
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 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000168ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */
Jari Aaltobb706242000-03-17 21:46:59 +0000169ITEMLIST it_functions = { 0, it_init_functions, (STRINGLIST *)0 };
Chet Rameyac50fba2014-02-26 09:36:43 -0500170ITEMLIST it_helptopics = { 0, it_init_helptopics, (STRINGLIST *)0 };
Jari Aaltobb706242000-03-17 21:46:59 +0000171ITEMLIST it_hostnames = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000172ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */
Jari Aaltof73dda02001-11-13 17:56:06 +0000173ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 };
Jari Aaltobb706242000-03-17 21:46:59 +0000174ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 };
175ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000176ITEMLIST it_services = { LIST_DYNAMIC }; /* unused */
Jari Aaltobb706242000-03-17 21:46:59 +0000177ITEMLIST 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 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000181ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
Jari Aaltobb706242000-03-17 21:46:59 +0000182ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
183
Jari Aalto31859422009-01-12 13:36:28 +0000184COMPSPEC *pcomp_curcs;
185const char *pcomp_curcmd;
Chet Ramey2b762662014-04-11 11:05:05 -0400186const char *pcomp_curtxt;
Jari Aalto31859422009-01-12 13:36:28 +0000187
Jari Aalto7117c2d2002-07-17 14:10:11 +0000188#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +0000189/* Debugging code */
Jari Aaltobb706242000-03-17 21:46:59 +0000190static 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
Jari Aalto7117c2d2002-07-17 14:10:11 +0000204 SH_VA_START (args, format);
Jari Aaltobb706242000-03-17 21:46:59 +0000205
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}
Jari Aalto7117c2d2002-07-17 14:10:11 +0000214#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000215
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)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000244 strvec_flush (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000245 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
Jari Aaltobb706242000-03-17 21:46:59 +0000253
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;
276 char *text;
277{
278 char *ret;
279
280 ret = strcreplace (pat, '&', text, 1);
281 return ret;
282}
283
284/* Remove any match of FILTERPAT from SL. A `&' in FILTERPAT is replaced by
285 TEXT. A leading `!' in FILTERPAT negates the pattern; in this case
286 any member of SL->list that does *not* match will be removed. This returns
287 a new STRINGLIST with the matching members of SL *copied*. Any
288 non-matching members of SL->list are *freed*. */
289STRINGLIST *
290filter_stringlist (sl, filterpat, text)
291 STRINGLIST *sl;
292 char *filterpat, *text;
293{
294 int i, m, not;
295 STRINGLIST *ret;
296 char *npat, *t;
297
298 if (sl == 0 || sl->list == 0 || sl->list_len == 0)
299 return sl;
300
301 npat = shouldexp_filterpat (filterpat) ? preproc_filterpat (filterpat, text) : filterpat;
302
303 not = (npat[0] == '!');
304 t = not ? npat + 1 : npat;
305
Jari Aalto7117c2d2002-07-17 14:10:11 +0000306 ret = strlist_create (sl->list_size);
Jari Aaltobb706242000-03-17 21:46:59 +0000307 for (i = 0; i < sl->list_len; i++)
308 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000309 m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);
Jari Aaltobb706242000-03-17 21:46:59 +0000310 if ((not && m == FNM_NOMATCH) || (not == 0 && m != FNM_NOMATCH))
311 free (sl->list[i]);
312 else
313 ret->list[ret->list_len++] = sl->list[i];
314 }
315
316 ret->list[ret->list_len] = (char *)NULL;
317 if (npat != filterpat)
318 free (npat);
319
320 return ret;
321}
322
Jari Aalto28ef6c32001-04-06 19:14:31 +0000323/* Turn an array of strings returned by rl_completion_matches into a STRINGLIST.
324 This understands how rl_completion_matches sets matches[0] (the lcd of the
Jari Aaltobb706242000-03-17 21:46:59 +0000325 strings in the list, unless it's the only match). */
326STRINGLIST *
327completions_to_stringlist (matches)
328 char **matches;
329{
330 STRINGLIST *sl;
331 int mlen, i, n;
332
Jari Aalto7117c2d2002-07-17 14:10:11 +0000333 mlen = (matches == 0) ? 0 : strvec_len (matches);
334 sl = strlist_create (mlen + 1);
Jari Aaltobb706242000-03-17 21:46:59 +0000335
336 if (matches == 0 || matches[0] == 0)
337 return sl;
338
339 if (matches[1] == 0)
340 {
341 sl->list[0] = STRDUP (matches[0]);
342 sl->list[sl->list_len = 1] = (char *)NULL;
343 return sl;
344 }
345
346 for (i = 1, n = 0; i < mlen; i++, n++)
347 sl->list[n] = STRDUP (matches[i]);
348 sl->list_len = n;
349 sl->list[n] = (char *)NULL;
350
351 return sl;
352}
353
354/* Functions to manage the various ITEMLISTs that we populate internally.
355 The caller is responsible for setting ITP->flags correctly. */
356
357static int
358it_init_aliases (itp)
359 ITEMLIST *itp;
360{
361#ifdef ALIAS
Jari Aaltof73dda02001-11-13 17:56:06 +0000362 alias_t **alias_list;
Jari Aaltobb706242000-03-17 21:46:59 +0000363 register int i, n;
364 STRINGLIST *sl;
365
Jari Aaltof73dda02001-11-13 17:56:06 +0000366 alias_list = all_aliases ();
367 if (alias_list == 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000368 {
369 itp->slist = (STRINGLIST *)NULL;
370 return 0;
371 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000372 for (n = 0; alias_list[n]; n++)
Jari Aaltobb706242000-03-17 21:46:59 +0000373 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000374 sl = strlist_create (n+1);
Jari Aaltobb706242000-03-17 21:46:59 +0000375 for (i = 0; i < n; i++)
Jari Aaltof73dda02001-11-13 17:56:06 +0000376 sl->list[i] = STRDUP (alias_list[i]->name);
Jari Aaltobb706242000-03-17 21:46:59 +0000377 sl->list[n] = (char *)NULL;
378 sl->list_size = sl->list_len = n;
379 itp->slist = sl;
380#else
381 itp->slist = (STRINGLIST *)NULL;
382#endif
Chet Rameyac50fba2014-02-26 09:36:43 -0500383 free (alias_list);
Jari Aaltobb706242000-03-17 21:46:59 +0000384 return 1;
385}
386
387static void
388init_itemlist_from_varlist (itp, svfunc)
389 ITEMLIST *itp;
390 SVFUNC *svfunc;
391{
392 SHELL_VAR **vlist;
393 STRINGLIST *sl;
394 register int i, n;
395
396 vlist = (*svfunc) ();
Jari Aaltob80f6442004-07-27 13:29:18 +0000397 if (vlist == 0)
398 {
399 itp->slist = (STRINGLIST *)NULL;
400 return;
401 }
Jari Aaltobb706242000-03-17 21:46:59 +0000402 for (n = 0; vlist[n]; n++)
403 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000404 sl = strlist_create (n+1);
Jari Aaltobb706242000-03-17 21:46:59 +0000405 for (i = 0; i < n; i++)
406 sl->list[i] = savestring (vlist[i]->name);
407 sl->list[sl->list_len = n] = (char *)NULL;
408 itp->slist = sl;
409}
410
411static int
412it_init_arrayvars (itp)
413 ITEMLIST *itp;
414{
415#if defined (ARRAY_VARS)
416 init_itemlist_from_varlist (itp, all_array_variables);
417 return 1;
418#else
419 return 0;
420#endif
421}
422
423static int
424it_init_bindings (itp)
425 ITEMLIST *itp;
426{
427 char **blist;
428 STRINGLIST *sl;
429
430 /* rl_funmap_names allocates blist, but not its members */
Jari Aaltof73dda02001-11-13 17:56:06 +0000431 blist = (char **)rl_funmap_names (); /* XXX fix const later */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000432 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000433 sl->list = blist;
434 sl->list_size = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000435 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000436 itp->flags |= LIST_DONTFREEMEMBERS;
437 itp->slist = sl;
438
439 return 0;
440}
441
442static int
443it_init_builtins (itp)
444 ITEMLIST *itp;
445{
446 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000447 register int i, n;
448
Jari Aalto7117c2d2002-07-17 14:10:11 +0000449 sl = strlist_create (num_shell_builtins);
Jari Aaltobb706242000-03-17 21:46:59 +0000450 for (i = n = 0; i < num_shell_builtins; i++)
451 if (shell_builtins[i].function)
452 sl->list[n++] = shell_builtins[i].name;
453 sl->list[sl->list_len = n] = (char *)NULL;
454 itp->flags |= LIST_DONTFREEMEMBERS;
455 itp->slist = sl;
456 return 0;
457}
458
459static int
460it_init_enabled (itp)
461 ITEMLIST *itp;
462{
463 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000464 register int i, n;
465
Jari Aalto7117c2d2002-07-17 14:10:11 +0000466 sl = strlist_create (num_shell_builtins);
Jari Aaltobb706242000-03-17 21:46:59 +0000467 for (i = n = 0; i < num_shell_builtins; i++)
468 {
469 if (shell_builtins[i].function && (shell_builtins[i].flags & BUILTIN_ENABLED))
470 sl->list[n++] = shell_builtins[i].name;
471 }
472 sl->list[sl->list_len = n] = (char *)NULL;
473 itp->flags |= LIST_DONTFREEMEMBERS;
474 itp->slist = sl;
475 return 0;
476}
477
478static int
479it_init_disabled (itp)
480 ITEMLIST *itp;
481{
482 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000483 register int i, n;
484
Jari Aalto7117c2d2002-07-17 14:10:11 +0000485 sl = strlist_create (num_shell_builtins);
Jari Aaltobb706242000-03-17 21:46:59 +0000486 for (i = n = 0; i < num_shell_builtins; i++)
487 {
488 if (shell_builtins[i].function && ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
489 sl->list[n++] = shell_builtins[i].name;
490 }
491 sl->list[sl->list_len = n] = (char *)NULL;
492 itp->flags |= LIST_DONTFREEMEMBERS;
493 itp->slist = sl;
494 return 0;
495}
496
497static int
498it_init_exported (itp)
499 ITEMLIST *itp;
500{
501 init_itemlist_from_varlist (itp, all_exported_variables);
502 return 0;
503}
504
505static int
506it_init_functions (itp)
507 ITEMLIST *itp;
508{
509 init_itemlist_from_varlist (itp, all_visible_functions);
510 return 0;
511}
512
Chet Rameyac50fba2014-02-26 09:36:43 -0500513/* Like it_init_builtins, but includes everything the help builtin looks at,
514 not just builtins with an active implementing function. */
515static int
516it_init_helptopics (itp)
517 ITEMLIST *itp;
518{
519 STRINGLIST *sl;
520 register int i, n;
521
522 sl = strlist_create (num_shell_builtins);
523 for (i = n = 0; i < num_shell_builtins; i++)
524 sl->list[n++] = shell_builtins[i].name;
525 sl->list[sl->list_len = n] = (char *)NULL;
526 itp->flags |= LIST_DONTFREEMEMBERS;
527 itp->slist = sl;
528 return 0;
529}
530
Jari Aaltobb706242000-03-17 21:46:59 +0000531static int
532it_init_hostnames (itp)
533 ITEMLIST *itp;
534{
535 STRINGLIST *sl;
536
Jari Aalto7117c2d2002-07-17 14:10:11 +0000537 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000538 sl->list = get_hostname_list ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000539 sl->list_len = sl->list ? strvec_len (sl->list) : 0;
Jari Aaltobb706242000-03-17 21:46:59 +0000540 sl->list_size = sl->list_len;
541 itp->slist = sl;
542 itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE;
543 return 0;
544}
545
546static int
547it_init_joblist (itp, jstate)
548 ITEMLIST *itp;
549 int jstate;
550{
551#if defined (JOB_CONTROL)
552 STRINGLIST *sl;
Jari Aaltof73dda02001-11-13 17:56:06 +0000553 register int i;
Jari Aaltobb706242000-03-17 21:46:59 +0000554 register PROCESS *p;
555 char *s, *t;
Jari Aalto95732b42005-12-07 14:08:12 +0000556 JOB *j;
557 JOB_STATE ws; /* wanted state */
Jari Aaltobb706242000-03-17 21:46:59 +0000558
Jari Aalto31859422009-01-12 13:36:28 +0000559 ws = JNONE;
Jari Aaltobb706242000-03-17 21:46:59 +0000560 if (jstate == 0)
Jari Aalto95732b42005-12-07 14:08:12 +0000561 ws = JRUNNING;
Jari Aaltobb706242000-03-17 21:46:59 +0000562 else if (jstate == 1)
Jari Aalto95732b42005-12-07 14:08:12 +0000563 ws = JSTOPPED;
Jari Aaltobb706242000-03-17 21:46:59 +0000564
Jari Aalto95732b42005-12-07 14:08:12 +0000565 sl = strlist_create (js.j_jobslots);
566 for (i = js.j_jobslots - 1; i >= 0; i--)
Jari Aaltobb706242000-03-17 21:46:59 +0000567 {
Jari Aalto95732b42005-12-07 14:08:12 +0000568 j = get_job_by_jid (i);
569 if (j == 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000570 continue;
Jari Aalto95732b42005-12-07 14:08:12 +0000571 p = j->pipe;
572 if (jstate == -1 || JOBSTATE(i) == ws)
Jari Aaltobb706242000-03-17 21:46:59 +0000573 {
574 s = savestring (p->command);
575 t = strpbrk (s, " \t\n");
576 if (t)
577 *t = '\0';
Jari Aalto28ef6c32001-04-06 19:14:31 +0000578 sl->list[sl->list_len++] = s;
Jari Aaltobb706242000-03-17 21:46:59 +0000579 }
580 }
581 itp->slist = sl;
582#else
583 itp->slist = (STRINGLIST *)NULL;
584#endif
585 return 0;
586}
587
588static int
589it_init_jobs (itp)
590 ITEMLIST *itp;
591{
592 return (it_init_joblist (itp, -1));
593}
594
595static int
596it_init_running (itp)
597 ITEMLIST *itp;
598{
599 return (it_init_joblist (itp, 0));
600}
601
602static int
603it_init_stopped (itp)
604 ITEMLIST *itp;
605{
606 return (it_init_joblist (itp, 1));
607}
608
609static int
610it_init_keywords (itp)
611 ITEMLIST *itp;
612{
613 STRINGLIST *sl;
614 register int i, n;
615
616 for (n = 0; word_token_alist[n].word; n++)
617 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000618 sl = strlist_create (n);
Jari Aaltobb706242000-03-17 21:46:59 +0000619 for (i = 0; i < n; i++)
620 sl->list[i] = word_token_alist[i].word;
621 sl->list[sl->list_len = i] = (char *)NULL;
622 itp->flags |= LIST_DONTFREEMEMBERS;
623 itp->slist = sl;
624 return 0;
625}
626
627static int
628it_init_signals (itp)
629 ITEMLIST *itp;
630{
631 STRINGLIST *sl;
632
Jari Aalto7117c2d2002-07-17 14:10:11 +0000633 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000634 sl->list = signal_names;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000635 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000636 itp->flags |= LIST_DONTFREE;
637 itp->slist = sl;
638 return 0;
639}
640
641static int
642it_init_variables (itp)
643 ITEMLIST *itp;
644{
645 init_itemlist_from_varlist (itp, all_visible_variables);
646 return 0;
647}
648
649static int
650it_init_setopts (itp)
651 ITEMLIST *itp;
652{
653 STRINGLIST *sl;
654
Jari Aalto7117c2d2002-07-17 14:10:11 +0000655 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000656 sl->list = get_minus_o_opts ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000657 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000658 itp->slist = sl;
659 itp->flags |= LIST_DONTFREEMEMBERS;
660 return 0;
661}
662
663static int
664it_init_shopts (itp)
665 ITEMLIST *itp;
666{
667 STRINGLIST *sl;
668
Jari Aalto7117c2d2002-07-17 14:10:11 +0000669 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000670 sl->list = get_shopt_options ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000671 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000672 itp->slist = sl;
673 itp->flags |= LIST_DONTFREEMEMBERS;
674 return 0;
675}
676
677/* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
678 as the list of possibilities. If the itemlist has been marked dirty or
679 it should be regenerated every time, destroy the old STRINGLIST and make a
Jari Aaltob80f6442004-07-27 13:29:18 +0000680 new one before trying the match. TEXT is dequoted before attempting a
681 match. */
Jari Aaltobb706242000-03-17 21:46:59 +0000682static STRINGLIST *
683gen_matches_from_itemlist (itp, text)
684 ITEMLIST *itp;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000685 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000686{
687 STRINGLIST *ret, *sl;
688 int tlen, i, n;
Jari Aaltob80f6442004-07-27 13:29:18 +0000689 char *ntxt;
Jari Aaltobb706242000-03-17 21:46:59 +0000690
691 if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
692 (itp->flags & LIST_INITIALIZED) == 0)
693 {
Chet Ramey00018032011-11-21 20:51:19 -0500694 if (itp->flags & (LIST_DIRTY|LIST_DYNAMIC))
Jari Aaltobb706242000-03-17 21:46:59 +0000695 clean_itemlist (itp);
696 if ((itp->flags & LIST_INITIALIZED) == 0)
697 initialize_itemlist (itp);
698 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000699 if (itp->slist == 0)
700 return ((STRINGLIST *)NULL);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000701 ret = strlist_create (itp->slist->list_len+1);
Jari Aaltobb706242000-03-17 21:46:59 +0000702 sl = itp->slist;
Jari Aaltob80f6442004-07-27 13:29:18 +0000703
704 ntxt = bash_dequote_text (text);
705 tlen = STRLEN (ntxt);
706
Jari Aaltobb706242000-03-17 21:46:59 +0000707 for (i = n = 0; i < sl->list_len; i++)
708 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000709 if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
Jari Aaltobb706242000-03-17 21:46:59 +0000710 ret->list[n++] = STRDUP (sl->list[i]);
711 }
712 ret->list[ret->list_len = n] = (char *)NULL;
Jari Aaltob80f6442004-07-27 13:29:18 +0000713
714 FREE (ntxt);
Jari Aaltobb706242000-03-17 21:46:59 +0000715 return ret;
716}
717
Jari Aalto28ef6c32001-04-06 19:14:31 +0000718/* A wrapper for rl_filename_completion_function that dequotes the filename
Jari Aaltobb706242000-03-17 21:46:59 +0000719 before attempting completions. */
720static char *
721pcomp_filename_completion_function (text, state)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000722 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000723 int state;
724{
725 static char *dfn; /* dequoted filename */
726 int qc;
Chet Rameyac50fba2014-02-26 09:36:43 -0500727 int iscompgen, iscompleting;
Jari Aaltobb706242000-03-17 21:46:59 +0000728
729 if (state == 0)
730 {
731 FREE (dfn);
732 /* remove backslashes quoting special characters in filenames. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500733 /* There are roughly three paths we can follow to get here:
734 1. complete -f
735 2. compgen -f "$word" from a completion function
736 3. compgen -f "$word" from the command line
737 They all need to be handled.
738
739 In the first two cases, readline will run the filename dequoting
740 function in rl_filename_completion_function if it found a filename
741 quoting character in the word to be completed
742 (rl_completion_found_quote). We run the dequoting function here
743 if we're running compgen, we're not completing, and the
744 rl_filename_completion_function won't dequote the filename
745 (rl_completion_found_quote == 0). */
746 iscompgen = this_shell_builtin == compgen_builtin;
747 iscompleting = RL_ISSTATE (RL_STATE_COMPLETING);
748 if (iscompgen && iscompleting == 0 && rl_completion_found_quote == 0
749 && rl_filename_dequoting_function)
Jari Aalto31859422009-01-12 13:36:28 +0000750 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000751 /* Use rl_completion_quote_character because any single or
752 double quotes have been removed by the time TEXT makes it
753 here, and we don't want to remove backslashes inside
754 quoted strings. */
Jari Aalto31859422009-01-12 13:36:28 +0000755 dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
Jari Aaltobb706242000-03-17 21:46:59 +0000756 }
Chet Ramey2b762662014-04-11 11:05:05 -0400757 /* Intended to solve a mismatched assumption by bash-completion. If
758 the text to be completed is empty, but bash-completion turns it into
759 a quoted string ('') assuming that this code will dequote it before
760 calling readline, do the dequoting. */
761 else if (iscompgen && iscompleting &&
762 pcomp_curtxt && *pcomp_curtxt == 0 &&
763 text && (*text == '\'' || *text == '"') && text[1] == text[0] && text[2] == 0 &&
764 rl_filename_dequoting_function)
765 dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
766 /* Another mismatched assumption by bash-completion. If compgen is being
767 run as part of bash-completion, and the argument to compgen is not
768 the same as the word originally passed to the programmable completion
769 code, dequote the argument if it has quote characters. It's an
770 attempt to detect when bash-completion is quoting its filename
771 argument before calling compgen. */
772 /* We could check whether gen_shell_function_matches is in the call
773 stack by checking whether the gen-shell-function-matches tag is in
774 the unwind-protect stack, but there's no function to do that yet.
775 We could simply check whether we're executing in a function by
776 checking variable_context, and may end up doing that. */
777 else if (iscompgen && iscompleting && rl_filename_dequoting_function &&
778 pcomp_curtxt && text &&
779 STREQ (pcomp_curtxt, text) == 0 &&
780 variable_context &&
781 sh_contains_quotes (text)) /* guess */
782 dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
Jari Aaltobb706242000-03-17 21:46:59 +0000783 else
784 dfn = savestring (text);
785 }
786
Jari Aalto28ef6c32001-04-06 19:14:31 +0000787 return (rl_filename_completion_function (dfn, state));
Jari Aaltobb706242000-03-17 21:46:59 +0000788}
789
790#define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
791 do { \
792 if (bmap & flag) \
793 { \
794 tlist = gen_matches_from_itemlist (it, text); \
Jari Aaltof73dda02001-11-13 17:56:06 +0000795 if (tlist) \
796 { \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000797 glist = strlist_append (glist, tlist); \
798 strlist_dispose (tlist); \
Jari Aaltof73dda02001-11-13 17:56:06 +0000799 } \
Jari Aaltobb706242000-03-17 21:46:59 +0000800 } \
801 } while (0)
802
803#define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
804 do { \
805 if (bmap & flag) \
806 { \
Jari Aalto28ef6c32001-04-06 19:14:31 +0000807 cmatches = rl_completion_matches (text, func); \
Jari Aaltobb706242000-03-17 21:46:59 +0000808 tlist = completions_to_stringlist (cmatches); \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000809 glist = strlist_append (glist, tlist); \
810 strvec_dispose (cmatches); \
811 strlist_dispose (tlist); \
Jari Aaltobb706242000-03-17 21:46:59 +0000812 } \
813 } while (0)
814
815/* Functions to generate lists of matches from the actions member of CS. */
816
817static STRINGLIST *
818gen_action_completions (cs, text)
819 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000820 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000821{
822 STRINGLIST *ret, *tmatches;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000823 char **cmatches; /* from rl_completion_matches ... */
Jari Aaltobb706242000-03-17 21:46:59 +0000824 unsigned long flags;
Chet Rameyac50fba2014-02-26 09:36:43 -0500825 int t;
Jari Aaltobb706242000-03-17 21:46:59 +0000826
827 ret = tmatches = (STRINGLIST *)NULL;
828 flags = cs->actions;
829
830 GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches);
831 GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches);
832 GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches);
833 GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches);
834 GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches);
835 GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches);
836 GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches);
837 GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches);
Chet Rameyac50fba2014-02-26 09:36:43 -0500838 GEN_COMPS (flags, CA_HELPTOPIC, &it_helptopics, text, ret, tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +0000839 GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches);
840 GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches);
841 GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches);
842 GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches);
843 GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches);
844 GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches);
845 GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches);
846 GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches);
847 GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches);
848
849 GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches);
850 GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000851 GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
Jari Aaltof73dda02001-11-13 17:56:06 +0000852 GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000853 GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +0000854
855 /* And lastly, the special case for directories */
856 if (flags & CA_DIRECTORY)
857 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500858 t = rl_filename_completion_desired;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000859 rl_completion_mark_symlink_dirs = 1; /* override user preference */
Jari Aaltobb706242000-03-17 21:46:59 +0000860 cmatches = bash_directory_completion_matches (text);
Chet Rameyac50fba2014-02-26 09:36:43 -0500861 /* If we did not want filename completion before this, and there are
862 no matches, turn off rl_filename_completion_desired so whatever
863 matches we get are not treated as filenames (it gets turned on by
864 rl_filename_completion_function unconditionally). */
865 if (t == 0 && cmatches == 0 && rl_filename_completion_desired == 1)
866 rl_filename_completion_desired = 0;
Jari Aaltobb706242000-03-17 21:46:59 +0000867 tmatches = completions_to_stringlist (cmatches);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000868 ret = strlist_append (ret, tmatches);
869 strvec_dispose (cmatches);
870 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +0000871 }
872
873 return ret;
874}
875
876/* Generate a list of matches for CS->globpat. Unresolved: should this use
877 TEXT as a match prefix, or just go without? Currently, the code does not
878 use TEXT, just globs CS->globpat and returns the results. If we do decide
879 to use TEXT, we should call quote_string_for_globbing before the call to
880 glob_filename. */
881static STRINGLIST *
882gen_globpat_matches (cs, text)
883 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000884 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000885{
886 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000887
Jari Aalto7117c2d2002-07-17 14:10:11 +0000888 sl = strlist_create (0);
889 sl->list = glob_filename (cs->globpat, 0);
Jari Aaltobb706242000-03-17 21:46:59 +0000890 if (GLOB_FAILED (sl->list))
891 sl->list = (char **)NULL;
892 if (sl->list)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000893 sl->list_len = sl->list_size = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000894 return sl;
895}
896
897/* Perform the shell word expansions on CS->words and return the results.
898 Again, this ignores TEXT. */
899static STRINGLIST *
900gen_wordlist_matches (cs, text)
901 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000902 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000903{
904 WORD_LIST *l, *l2;
905 STRINGLIST *sl;
Jari Aalto06285672006-10-10 14:15:34 +0000906 int nw, tlen;
Jari Aaltob80f6442004-07-27 13:29:18 +0000907 char *ntxt; /* dequoted TEXT to use in comparisons */
Jari Aaltobb706242000-03-17 21:46:59 +0000908
909 if (cs->words == 0 || cs->words[0] == '\0')
910 return ((STRINGLIST *)NULL);
911
912 /* This used to be a simple expand_string(cs->words, 0), but that won't
913 do -- there's no way to split a simple list into individual words
914 that way, since the shell semantics say that word splitting is done
Chet Rameyac50fba2014-02-26 09:36:43 -0500915 only on the results of expansion. split_at_delims also handles embedded
916 quoted strings and preserves the quotes for the expand_words_shellexp
917 function call that follows. */
918 /* XXX - this is where this function spends most of its time */
Chet Ramey00018032011-11-21 20:51:19 -0500919 l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, 0, (int *)NULL, (int *)NULL);
Jari Aaltobb706242000-03-17 21:46:59 +0000920 if (l == 0)
921 return ((STRINGLIST *)NULL);
922 /* This will jump back to the top level if the expansion fails... */
923 l2 = expand_words_shellexp (l);
924 dispose_words (l);
925
926 nw = list_length (l2);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000927 sl = strlist_create (nw + 1);
Jari Aaltob80f6442004-07-27 13:29:18 +0000928
929 ntxt = bash_dequote_text (text);
930 tlen = STRLEN (ntxt);
Jari Aaltobb706242000-03-17 21:46:59 +0000931
932 for (nw = 0, l = l2; l; l = l->next)
933 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000934 if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
Jari Aalto28ef6c32001-04-06 19:14:31 +0000935 sl->list[nw++] = STRDUP (l->word->word);
Jari Aaltobb706242000-03-17 21:46:59 +0000936 }
937 sl->list[sl->list_len = nw] = (char *)NULL;
938
Jari Aalto95732b42005-12-07 14:08:12 +0000939 dispose_words (l2);
Jari Aaltob80f6442004-07-27 13:29:18 +0000940 FREE (ntxt);
Jari Aaltobb706242000-03-17 21:46:59 +0000941 return sl;
942}
943
944#ifdef ARRAY_VARS
945
946static SHELL_VAR *
947bind_comp_words (lwords)
948 WORD_LIST *lwords;
949{
950 SHELL_VAR *v;
951
952 v = find_variable ("COMP_WORDS");
953 if (v == 0)
954 v = make_new_array_variable ("COMP_WORDS");
955 if (readonly_p (v))
956 VUNSETATTR (v, att_readonly);
957 if (array_p (v) == 0)
958 v = convert_var_to_array (v);
Jari Aalto95732b42005-12-07 14:08:12 +0000959 v = assign_array_var_from_word_list (v, lwords, 0);
Jari Aaltoeb873672004-11-09 21:37:25 +0000960
961 VUNSETATTR (v, att_invisible);
Jari Aaltobb706242000-03-17 21:46:59 +0000962 return v;
963}
964#endif /* ARRAY_VARS */
965
966static void
967bind_compfunc_variables (line, ind, lwords, cw, exported)
968 char *line;
969 int ind;
970 WORD_LIST *lwords;
971 int cw, exported;
972{
Jari Aaltof73dda02001-11-13 17:56:06 +0000973 char ibuf[INT_STRLEN_BOUND(int) + 1];
Jari Aaltobb706242000-03-17 21:46:59 +0000974 char *value;
975 SHELL_VAR *v;
Chet Rameyac50fba2014-02-26 09:36:43 -0500976 size_t llen;
977 int c;
Jari Aaltobb706242000-03-17 21:46:59 +0000978
979 /* Set the variables that the function expects while it executes. Maybe
980 these should be in the function environment (temporary_env). */
Jari Aalto95732b42005-12-07 14:08:12 +0000981 v = bind_variable ("COMP_LINE", line, 0);
Jari Aaltobb706242000-03-17 21:46:59 +0000982 if (v && exported)
983 VSETATTR(v, att_exported);
984
Chet Rameyac50fba2014-02-26 09:36:43 -0500985 /* Post bash-4.2: COMP_POINT is characters instead of bytes. */
986 c = line[ind];
987 line[ind] = '\0';
988 llen = MB_STRLEN (line);
989 line[ind] = c;
990 value = inttostr (llen, ibuf, sizeof(ibuf));
Jari Aaltobb706242000-03-17 21:46:59 +0000991 v = bind_int_variable ("COMP_POINT", value);
992 if (v && exported)
993 VSETATTR(v, att_exported);
994
Jari Aalto31859422009-01-12 13:36:28 +0000995 value = inttostr (rl_completion_type, ibuf, sizeof (ibuf));
996 v = bind_int_variable ("COMP_TYPE", value);
997 if (v && exported)
998 VSETATTR(v, att_exported);
999
1000 value = inttostr (rl_completion_invoking_key, ibuf, sizeof (ibuf));
1001 v = bind_int_variable ("COMP_KEY", value);
1002 if (v && exported)
1003 VSETATTR(v, att_exported);
1004
Jari Aaltobb706242000-03-17 21:46:59 +00001005 /* Since array variables can't be exported, we don't bother making the
1006 array of words. */
1007 if (exported == 0)
1008 {
1009#ifdef ARRAY_VARS
1010 v = bind_comp_words (lwords);
Jari Aaltof73dda02001-11-13 17:56:06 +00001011 value = inttostr (cw, ibuf, sizeof(ibuf));
Jari Aaltobb706242000-03-17 21:46:59 +00001012 bind_int_variable ("COMP_CWORD", value);
1013#endif
1014 }
1015 else
1016 array_needs_making = 1;
1017}
1018
1019static void
1020unbind_compfunc_variables (exported)
1021 int exported;
1022{
Jari Aalto7117c2d2002-07-17 14:10:11 +00001023 unbind_variable ("COMP_LINE");
1024 unbind_variable ("COMP_POINT");
Jari Aalto31859422009-01-12 13:36:28 +00001025 unbind_variable ("COMP_TYPE");
1026 unbind_variable ("COMP_KEY");
Jari Aaltobb706242000-03-17 21:46:59 +00001027#ifdef ARRAY_VARS
Jari Aalto7117c2d2002-07-17 14:10:11 +00001028 unbind_variable ("COMP_WORDS");
1029 unbind_variable ("COMP_CWORD");
Jari Aaltobb706242000-03-17 21:46:59 +00001030#endif
1031 if (exported)
1032 array_needs_making = 1;
1033}
1034
1035/* Build the list of words to pass to a function or external command
1036 as arguments. When the function or command is invoked,
1037
1038 $0 == function or command being invoked
1039 $1 == command name
Jari Aalto17345e52009-02-19 22:21:29 +00001040 $2 == word to be completed (possibly null)
1041 $3 == previous word
Jari Aaltobb706242000-03-17 21:46:59 +00001042
1043 Functions can access all of the words in the current command line
Jari Aalto17345e52009-02-19 22:21:29 +00001044 with the COMP_WORDS array. External commands cannot; they have to
Chet Rameyac50fba2014-02-26 09:36:43 -05001045 make do with the COMP_LINE and COMP_POINT variables. */
Jari Aaltobb706242000-03-17 21:46:59 +00001046
1047static WORD_LIST *
Chet Rameyac50fba2014-02-26 09:36:43 -05001048build_arg_list (cmd, cname, text, lwords, ind)
Jari Aaltobb706242000-03-17 21:46:59 +00001049 char *cmd;
Chet Rameyac50fba2014-02-26 09:36:43 -05001050 const char *cname;
Jari Aaltof73dda02001-11-13 17:56:06 +00001051 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +00001052 WORD_LIST *lwords;
1053 int ind;
1054{
1055 WORD_LIST *ret, *cl, *l;
1056 WORD_DESC *w;
1057 int i;
1058
1059 ret = (WORD_LIST *)NULL;
1060 w = make_word (cmd);
Chet Rameyac50fba2014-02-26 09:36:43 -05001061 ret = make_word_list (w, (WORD_LIST *)NULL); /* $0 */
Jari Aaltobb706242000-03-17 21:46:59 +00001062
Chet Rameyac50fba2014-02-26 09:36:43 -05001063 w = make_word (cname); /* $1 */
Jari Aaltobb706242000-03-17 21:46:59 +00001064 cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
1065
1066 w = make_word (text);
Chet Rameyac50fba2014-02-26 09:36:43 -05001067 cl->next = make_word_list (w, (WORD_LIST *)NULL); /* $2 */
Jari Aaltobb706242000-03-17 21:46:59 +00001068 cl = cl->next;
1069
1070 /* Search lwords for current word */
1071 for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
1072 ;
1073 w = (l && l->word) ? copy_word (l->word) : make_word ("");
1074 cl->next = make_word_list (w, (WORD_LIST *)NULL);
1075
1076 return ret;
1077}
1078
1079/* Build a command string with
1080 $0 == cs->funcname (function to execute for completion list)
1081 $1 == command name (command being completed)
1082 $2 = word to be completed (possibly null)
1083 $3 = previous word
1084 and run in the current shell. The function should put its completion
1085 list into the array variable COMPREPLY. We build a STRINGLIST
1086 from the results and return it.
1087
1088 Since the shell function should return its list of matches in an array
1089 variable, this does nothing if arrays are not compiled into the shell. */
1090
1091static STRINGLIST *
Chet Rameyac50fba2014-02-26 09:36:43 -05001092gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp)
Jari Aaltobb706242000-03-17 21:46:59 +00001093 COMPSPEC *cs;
Chet Rameyac50fba2014-02-26 09:36:43 -05001094 const char *cmd;
Jari Aaltof73dda02001-11-13 17:56:06 +00001095 const char *text;
1096 char *line;
Jari Aaltobb706242000-03-17 21:46:59 +00001097 int ind;
1098 WORD_LIST *lwords;
1099 int nw, cw;
Chet Ramey00018032011-11-21 20:51:19 -05001100 int *foundp;
Jari Aaltobb706242000-03-17 21:46:59 +00001101{
1102 char *funcname;
1103 STRINGLIST *sl;
1104 SHELL_VAR *f, *v;
1105 WORD_LIST *cmdlist;
Chet Ramey00018032011-11-21 20:51:19 -05001106 int fval, found;
Jari Aalto95732b42005-12-07 14:08:12 +00001107 sh_parser_state_t ps;
Jari Aalto17345e52009-02-19 22:21:29 +00001108 sh_parser_state_t * restrict pps;
Jari Aaltobb706242000-03-17 21:46:59 +00001109#if defined (ARRAY_VARS)
1110 ARRAY *a;
1111#endif
1112
Chet Ramey00018032011-11-21 20:51:19 -05001113 found = 0;
1114 if (foundp)
1115 *foundp = found;
1116
Jari Aaltobb706242000-03-17 21:46:59 +00001117 funcname = cs->funcname;
1118 f = find_function (funcname);
1119 if (f == 0)
1120 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001121 internal_error (_("completion: function `%s' not found"), funcname);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001122 rl_ding ();
Jari Aaltobb706242000-03-17 21:46:59 +00001123 rl_on_new_line ();
1124 return ((STRINGLIST *)NULL);
1125 }
1126
1127#if !defined (ARRAY_VARS)
1128 return ((STRINGLIST *)NULL);
1129#else
1130
1131 /* We pass cw - 1 because command_line_to_word_list returns indices that are
1132 1-based, while bash arrays are 0-based. */
1133 bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
1134
Chet Rameyac50fba2014-02-26 09:36:43 -05001135 cmdlist = build_arg_list (funcname, cmd, text, lwords, cw);
Jari Aalto95732b42005-12-07 14:08:12 +00001136
Jari Aalto17345e52009-02-19 22:21:29 +00001137 pps = &ps;
Chet Ramey89a92862011-11-21 20:49:12 -05001138 save_parser_state (pps);
Jari Aalto17345e52009-02-19 22:21:29 +00001139 begin_unwind_frame ("gen-shell-function-matches");
1140 add_unwind_protect (restore_parser_state, (char *)pps);
1141 add_unwind_protect (dispose_words, (char *)cmdlist);
1142 add_unwind_protect (unbind_compfunc_variables, (char *)0);
1143
Jari Aaltobb706242000-03-17 21:46:59 +00001144 fval = execute_shell_function (f, cmdlist);
Jari Aalto17345e52009-02-19 22:21:29 +00001145
1146 discard_unwind_frame ("gen-shell-function-matches");
1147 restore_parser_state (pps);
Jari Aaltobb706242000-03-17 21:46:59 +00001148
Chet Ramey00018032011-11-21 20:51:19 -05001149 found = fval != EX_NOTFOUND;
1150 if (fval == EX_RETRYFAIL)
1151 found |= PCOMP_RETRYFAIL;
1152 if (foundp)
1153 *foundp = found;
1154
Jari Aaltobb706242000-03-17 21:46:59 +00001155 /* Now clean up and destroy everything. */
1156 dispose_words (cmdlist);
1157 unbind_compfunc_variables (0);
1158
1159 /* The list of completions is returned in the array variable COMPREPLY. */
1160 v = find_variable ("COMPREPLY");
1161 if (v == 0)
1162 return ((STRINGLIST *)NULL);
1163 if (array_p (v) == 0)
1164 v = convert_var_to_array (v);
1165
Jari Aaltoeb873672004-11-09 21:37:25 +00001166 VUNSETATTR (v, att_invisible);
1167
Jari Aaltobb706242000-03-17 21:46:59 +00001168 a = array_cell (v);
Chet Ramey00018032011-11-21 20:51:19 -05001169 if (found == 0 || (found & PCOMP_RETRYFAIL) || a == 0 || array_empty (a))
Jari Aaltobb706242000-03-17 21:46:59 +00001170 sl = (STRINGLIST *)NULL;
1171 else
1172 {
1173 /* XXX - should we filter the list of completions so only those matching
1174 TEXT are returned? Right now, we do not. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001175 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +00001176 sl->list = array_to_argv (a);
1177 sl->list_len = sl->list_size = array_num_elements (a);
1178 }
1179
1180 /* XXX - should we unbind COMPREPLY here? */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001181 unbind_variable ("COMPREPLY");
Jari Aaltobb706242000-03-17 21:46:59 +00001182
1183 return (sl);
1184#endif
1185}
1186
1187/* Build a command string with
1188 $0 == cs->command (command to execute for completion list)
1189 $1 == command name (command being completed)
1190 $2 = word to be completed (possibly null)
1191 $3 = previous word
1192 and run in with command substitution. Parse the results, one word
1193 per line, with backslashes allowed to escape newlines. Build a
1194 STRINGLIST from the results and return it. */
1195
1196static STRINGLIST *
Chet Rameyac50fba2014-02-26 09:36:43 -05001197gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw)
Jari Aaltobb706242000-03-17 21:46:59 +00001198 COMPSPEC *cs;
Chet Rameyac50fba2014-02-26 09:36:43 -05001199 const char *cmd;
Jari Aaltof73dda02001-11-13 17:56:06 +00001200 const char *text;
1201 char *line;
Jari Aaltobb706242000-03-17 21:46:59 +00001202 int ind;
1203 WORD_LIST *lwords;
1204 int nw, cw;
1205{
1206 char *csbuf, *cscmd, *t;
1207 int cmdlen, cmdsize, n, ws, we;
1208 WORD_LIST *cmdlist, *cl;
Jari Aalto31859422009-01-12 13:36:28 +00001209 WORD_DESC *tw;
Jari Aaltobb706242000-03-17 21:46:59 +00001210 STRINGLIST *sl;
1211
1212 bind_compfunc_variables (line, ind, lwords, cw, 1);
Chet Rameyac50fba2014-02-26 09:36:43 -05001213 cmdlist = build_arg_list (cs->command, cmd, text, lwords, cw);
Jari Aaltobb706242000-03-17 21:46:59 +00001214
1215 /* Estimate the size needed for the buffer. */
1216 n = strlen (cs->command);
1217 cmdsize = n + 1;
1218 for (cl = cmdlist->next; cl; cl = cl->next)
1219 cmdsize += STRLEN (cl->word->word) + 3;
1220 cmdsize += 2;
1221
1222 /* allocate the string for the command and fill it in. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001223 cscmd = (char *)xmalloc (cmdsize + 1);
Jari Aaltobb706242000-03-17 21:46:59 +00001224
1225 strcpy (cscmd, cs->command); /* $0 */
1226 cmdlen = n;
1227 cscmd[cmdlen++] = ' ';
1228 for (cl = cmdlist->next; cl; cl = cl->next) /* $1, $2, $3, ... */
1229 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00001230 t = sh_single_quote (cl->word->word ? cl->word->word : "");
Jari Aaltobb706242000-03-17 21:46:59 +00001231 n = strlen (t);
1232 RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
1233 strcpy (cscmd + cmdlen, t);
1234 cmdlen += n;
1235 if (cl->next)
1236 cscmd[cmdlen++] = ' ';
1237 free (t);
1238 }
1239 cscmd[cmdlen] = '\0';
1240
Jari Aalto31859422009-01-12 13:36:28 +00001241 tw = command_substitute (cscmd, 0);
1242 csbuf = tw ? tw->word : (char *)NULL;
Chet Rameyac50fba2014-02-26 09:36:43 -05001243 if (tw)
1244 dispose_word_desc (tw);
Jari Aaltobb706242000-03-17 21:46:59 +00001245
1246 /* Now clean up and destroy everything. */
1247 dispose_words (cmdlist);
1248 free (cscmd);
1249 unbind_compfunc_variables (1);
1250
1251 if (csbuf == 0 || *csbuf == '\0')
1252 {
1253 FREE (csbuf);
1254 return ((STRINGLIST *)NULL);
1255 }
1256
1257 /* Now break CSBUF up at newlines, with backslash allowed to escape a
1258 newline, and put the individual words into a STRINGLIST. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001259 sl = strlist_create (16);
Jari Aaltobb706242000-03-17 21:46:59 +00001260 for (ws = 0; csbuf[ws]; )
1261 {
1262 we = ws;
1263 while (csbuf[we] && csbuf[we] != '\n')
1264 {
1265 if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
1266 we++;
1267 we++;
1268 }
1269 t = substring (csbuf, ws, we);
1270 if (sl->list_len >= sl->list_size - 1)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001271 strlist_resize (sl, sl->list_size + 16);
Jari Aaltobb706242000-03-17 21:46:59 +00001272 sl->list[sl->list_len++] = t;
1273 while (csbuf[we] == '\n') we++;
1274 ws = we;
1275 }
1276 sl->list[sl->list_len] = (char *)NULL;
1277
1278 free (csbuf);
1279 return (sl);
1280}
1281
1282static WORD_LIST *
1283command_line_to_word_list (line, llen, sentinel, nwp, cwp)
1284 char *line;
1285 int llen, sentinel, *nwp, *cwp;
1286{
1287 WORD_LIST *ret;
1288 char *delims;
1289
Chet Ramey00018032011-11-21 20:51:19 -05001290#if 0
1291 delims = "()<>;&| \t\n"; /* shell metacharacters break words */
1292#else
1293 delims = rl_completer_word_break_characters;
1294#endif
1295 ret = split_at_delims (line, llen, delims, sentinel, SD_NOQUOTEDELIM, nwp, cwp);
Jari Aaltobb706242000-03-17 21:46:59 +00001296 return (ret);
1297}
1298
1299/* Evaluate COMPSPEC *cs and return all matches for WORD. */
1300
1301STRINGLIST *
Chet Ramey00018032011-11-21 20:51:19 -05001302gen_compspec_completions (cs, cmd, word, start, end, foundp)
Jari Aaltobb706242000-03-17 21:46:59 +00001303 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001304 const char *cmd;
1305 const char *word;
Jari Aaltobb706242000-03-17 21:46:59 +00001306 int start, end;
Chet Ramey00018032011-11-21 20:51:19 -05001307 int *foundp;
Jari Aaltobb706242000-03-17 21:46:59 +00001308{
1309 STRINGLIST *ret, *tmatches;
Jari Aaltof73dda02001-11-13 17:56:06 +00001310 char *line;
Chet Ramey00018032011-11-21 20:51:19 -05001311 int llen, nw, cw, found, foundf;
Jari Aaltobb706242000-03-17 21:46:59 +00001312 WORD_LIST *lwords;
Chet Rameyac50fba2014-02-26 09:36:43 -05001313 WORD_DESC *lw;
Jari Aaltob80f6442004-07-27 13:29:18 +00001314 COMPSPEC *tcs;
Jari Aaltobb706242000-03-17 21:46:59 +00001315
Chet Ramey00018032011-11-21 20:51:19 -05001316 found = 1;
1317
Jari Aalto7117c2d2002-07-17 14:10:11 +00001318#ifdef DEBUG
1319 debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
1320 debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
1321#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001322 ret = gen_action_completions (cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001323#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001324 if (ret && progcomp_debug)
1325 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001326 debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001327 strlist_print (ret, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001328 rl_on_new_line ();
1329 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001330#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001331
1332 /* Now we start generating completions based on the other members of CS. */
1333 if (cs->globpat)
1334 {
1335 tmatches = gen_globpat_matches (cs, word);
1336 if (tmatches)
1337 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001338#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001339 if (progcomp_debug)
1340 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001341 debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001342 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001343 rl_on_new_line ();
1344 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001345#endif
1346 ret = strlist_append (ret, tmatches);
1347 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001348 rl_filename_completion_desired = 1;
1349 }
1350 }
1351
1352 if (cs->words)
1353 {
1354 tmatches = gen_wordlist_matches (cs, word);
1355 if (tmatches)
1356 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001357#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001358 if (progcomp_debug)
1359 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001360 debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001361 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001362 rl_on_new_line ();
1363 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001364#endif
1365 ret = strlist_append (ret, tmatches);
1366 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001367 }
1368 }
1369
1370 lwords = (WORD_LIST *)NULL;
1371 line = (char *)NULL;
1372 if (cs->command || cs->funcname)
1373 {
1374 /* If we have a command or function to execute, we need to first break
1375 the command line into individual words, find the number of words,
1376 and find the word in the list containing the word to be completed. */
1377 line = substring (rl_line_buffer, start, end);
1378 llen = end - start;
1379
Jari Aalto7117c2d2002-07-17 14:10:11 +00001380#ifdef DEBUG
Jari Aaltof73dda02001-11-13 17:56:06 +00001381 debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
Jari Aaltobb706242000-03-17 21:46:59 +00001382 line, llen, rl_point - start, &nw, &cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001383#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001384 lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
Chet Rameyac50fba2014-02-26 09:36:43 -05001385 /* If we skipped a NULL word at the beginning of the line, add it back */
1386 if (lwords && lwords->word && cmd[0] == 0 && lwords->word->word[0] != 0)
1387 {
1388 lw = make_bare_word (cmd);
1389 lwords = make_word_list (lw, lwords);
1390 nw++;
1391 cw++;
1392 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001393#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001394 if (lwords == 0 && llen > 0)
1395 debug_printf ("ERROR: command_line_to_word_list returns NULL");
1396 else if (progcomp_debug)
1397 {
1398 debug_printf ("command_line_to_word_list -->");
1399 printf ("\t");
1400 print_word_list (lwords, "!");
1401 printf ("\n");
1402 fflush(stdout);
1403 rl_on_new_line ();
1404 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001405#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001406 }
1407
1408 if (cs->funcname)
1409 {
Chet Ramey00018032011-11-21 20:51:19 -05001410 foundf = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -05001411 tmatches = gen_shell_function_matches (cs, cmd, word, line, rl_point - start, lwords, nw, cw, &foundf);
Chet Ramey00018032011-11-21 20:51:19 -05001412 if (foundf != 0)
1413 found = foundf;
Jari Aaltobb706242000-03-17 21:46:59 +00001414 if (tmatches)
1415 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001416#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001417 if (progcomp_debug)
1418 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001419 debug_printf ("gen_shell_function_matches (%p, %s, %s, %p, %d, %d) -->", cs, cmd, word, lwords, nw, cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001420 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001421 rl_on_new_line ();
1422 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001423#endif
1424 ret = strlist_append (ret, tmatches);
1425 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001426 }
1427 }
1428
1429 if (cs->command)
1430 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001431 tmatches = gen_command_matches (cs, cmd, word, line, rl_point - start, lwords, nw, cw);
Jari Aaltobb706242000-03-17 21:46:59 +00001432 if (tmatches)
1433 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001434#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001435 if (progcomp_debug)
1436 {
Chet Rameyac50fba2014-02-26 09:36:43 -05001437 debug_printf ("gen_command_matches (%p, %s, %s, %p, %d, %d) -->", cs, cmd, word, lwords, nw, cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001438 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001439 rl_on_new_line ();
1440 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001441#endif
1442 ret = strlist_append (ret, tmatches);
1443 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001444 }
1445 }
1446
1447 if (cs->command || cs->funcname)
1448 {
1449 if (lwords)
1450 dispose_words (lwords);
1451 FREE (line);
1452 }
1453
Chet Ramey00018032011-11-21 20:51:19 -05001454 if (foundp)
1455 *foundp = found;
1456
1457 if (found == 0 || (found & PCOMP_RETRYFAIL))
1458 {
1459 strlist_dispose (ret);
1460 return NULL;
1461 }
1462
Jari Aaltobb706242000-03-17 21:46:59 +00001463 if (cs->filterpat)
1464 {
1465 tmatches = filter_stringlist (ret, cs->filterpat, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001466#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001467 if (progcomp_debug)
1468 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001469 debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001470 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001471 rl_on_new_line ();
1472 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001473#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001474 if (ret && ret != tmatches)
1475 {
1476 FREE (ret->list);
1477 free (ret);
1478 }
1479 ret = tmatches;
1480 }
1481
1482 if (cs->prefix || cs->suffix)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001483 ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
Jari Aaltobb706242000-03-17 21:46:59 +00001484
Jari Aalto28ef6c32001-04-06 19:14:31 +00001485 /* If no matches have been generated and the user has specified that
1486 directory completion should be done as a default, call
1487 gen_action_completions again to generate a list of matching directory
1488 names. */
1489 if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
1490 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001491 tcs = compspec_create ();
1492 tcs->actions = CA_DIRECTORY;
Chet Rameyac50fba2014-02-26 09:36:43 -05001493 FREE (ret);
Jari Aaltob80f6442004-07-27 13:29:18 +00001494 ret = gen_action_completions (tcs, word);
1495 compspec_dispose (tcs);
1496 }
1497 else if (cs->options & COPT_PLUSDIRS)
1498 {
1499 tcs = compspec_create ();
1500 tcs->actions = CA_DIRECTORY;
1501 tmatches = gen_action_completions (tcs, word);
1502 ret = strlist_append (ret, tmatches);
1503 strlist_dispose (tmatches);
1504 compspec_dispose (tcs);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001505 }
1506
Jari Aaltobb706242000-03-17 21:46:59 +00001507 return (ret);
1508}
1509
Jari Aalto31859422009-01-12 13:36:28 +00001510void
1511pcomp_set_readline_variables (flags, nval)
1512 int flags, nval;
1513{
1514 /* If the user specified that the compspec returns filenames, make
1515 sure that readline knows it. */
1516 if (flags & COPT_FILENAMES)
1517 rl_filename_completion_desired = nval;
1518 /* If the user doesn't want a space appended, tell readline. */
1519 if (flags & COPT_NOSPACE)
1520 rl_completion_suppress_append = nval;
Chet Rameyac50fba2014-02-26 09:36:43 -05001521 /* The value here is inverted, since the default is on and the `noquote'
1522 option is supposed to turn it off */
1523 if (flags & COPT_NOQUOTE)
1524 rl_filename_quoting_desired = 1 - nval;
Jari Aalto31859422009-01-12 13:36:28 +00001525}
1526
1527/* Set or unset FLAGS in the options word of the current compspec.
1528 SET_OR_UNSET is 1 for setting, 0 for unsetting. */
1529void
1530pcomp_set_compspec_options (cs, flags, set_or_unset)
1531 COMPSPEC *cs;
1532 int flags, set_or_unset;
1533{
1534 if (cs == 0 && ((cs = pcomp_curcs) == 0))
1535 return;
1536 if (set_or_unset)
1537 cs->options |= flags;
1538 else
1539 cs->options &= ~flags;
1540}
1541
Chet Ramey00018032011-11-21 20:51:19 -05001542static STRINGLIST *
1543gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
1544 const char *ocmd;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001545 const char *cmd;
1546 const char *word;
Chet Ramey00018032011-11-21 20:51:19 -05001547 int start, end;
1548 int *foundp, *retryp;
1549 COMPSPEC **lastcs;
Jari Aaltobb706242000-03-17 21:46:59 +00001550{
Jari Aalto31859422009-01-12 13:36:28 +00001551 COMPSPEC *cs, *oldcs;
Chet Ramey2b762662014-04-11 11:05:05 -04001552 const char *oldcmd, *oldtxt;
Chet Ramey00018032011-11-21 20:51:19 -05001553 STRINGLIST *ret;
Jari Aaltobb706242000-03-17 21:46:59 +00001554
Chet Ramey00018032011-11-21 20:51:19 -05001555 cs = progcomp_search (ocmd);
1556
1557 if (cs == 0 || cs == *lastcs)
Chet Rameyac50fba2014-02-26 09:36:43 -05001558 {
1559#if 0
1560 if (foundp)
1561 *foundp = 0;
1562#endif
1563 return (NULL);
1564 }
Chet Ramey00018032011-11-21 20:51:19 -05001565
1566 if (*lastcs)
1567 compspec_dispose (*lastcs);
1568 cs->refcount++; /* XXX */
1569 *lastcs = cs;
Jari Aaltobb706242000-03-17 21:46:59 +00001570
Jari Aaltob80f6442004-07-27 13:29:18 +00001571 cs = compspec_copy (cs);
1572
Jari Aalto31859422009-01-12 13:36:28 +00001573 oldcs = pcomp_curcs;
1574 oldcmd = pcomp_curcmd;
Chet Ramey2b762662014-04-11 11:05:05 -04001575 oldtxt = pcomp_curtxt;
Jari Aalto31859422009-01-12 13:36:28 +00001576
1577 pcomp_curcs = cs;
1578 pcomp_curcmd = cmd;
Chet Ramey2b762662014-04-11 11:05:05 -04001579 pcomp_curtxt = word;
Jari Aalto31859422009-01-12 13:36:28 +00001580
Chet Ramey00018032011-11-21 20:51:19 -05001581 ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
Jari Aaltobb706242000-03-17 21:46:59 +00001582
Jari Aalto31859422009-01-12 13:36:28 +00001583 pcomp_curcs = oldcs;
1584 pcomp_curcmd = oldcmd;
Chet Ramey2b762662014-04-11 11:05:05 -04001585 pcomp_curtxt = oldtxt;
Jari Aalto31859422009-01-12 13:36:28 +00001586
Chet Ramey00018032011-11-21 20:51:19 -05001587 /* We need to conditionally handle setting *retryp here */
1588 if (retryp)
1589 *retryp = foundp && (*foundp & PCOMP_RETRYFAIL);
1590
1591 if (foundp)
1592 {
1593 *foundp &= ~PCOMP_RETRYFAIL;
1594 *foundp |= cs->options;
1595 }
1596
Jari Aaltob80f6442004-07-27 13:29:18 +00001597 compspec_dispose (cs);
Chet Ramey00018032011-11-21 20:51:19 -05001598 return ret;
1599}
1600
1601/* The driver function for the programmable completion code. Returns a list
1602 of matches for WORD, which is an argument to command CMD. START and END
1603 bound the command currently being completed in rl_line_buffer. */
1604char **
1605programmable_completions (cmd, word, start, end, foundp)
1606 const char *cmd;
1607 const char *word;
1608 int start, end, *foundp;
1609{
1610 COMPSPEC *cs, *lastcs;
1611 STRINGLIST *ret;
1612 char **rmatches, *t;
1613 int found, retry, count;
1614
1615 lastcs = 0;
1616 found = count = 0;
1617
1618 do
1619 {
1620 retry = 0;
1621
1622 /* We look at the basename of CMD if the full command does not have
1623 an associated COMPSPEC. */
1624 ret = gen_progcomp_completions (cmd, cmd, word, start, end, &found, &retry, &lastcs);
1625 if (found == 0)
1626 {
1627 t = strrchr (cmd, '/');
1628 if (t && *(++t))
1629 ret = gen_progcomp_completions (t, cmd, word, start, end, &found, &retry, &lastcs);
1630 }
1631
1632 if (found == 0)
1633 ret = gen_progcomp_completions (DEFAULTCMD, cmd, word, start, end, &found, &retry, &lastcs);
1634
1635 count++;
1636
1637 if (count > 32)
1638 {
1639 internal_warning ("programmable_completion: %s: possible retry loop", cmd);
1640 break;
1641 }
1642 }
1643 while (retry);
Jari Aaltob80f6442004-07-27 13:29:18 +00001644
Jari Aaltobb706242000-03-17 21:46:59 +00001645 if (ret)
1646 {
1647 rmatches = ret->list;
1648 free (ret);
1649 }
1650 else
1651 rmatches = (char **)NULL;
1652
Chet Ramey00018032011-11-21 20:51:19 -05001653 if (foundp)
1654 *foundp = found;
1655
1656 if (lastcs) /* XXX - should be while? */
1657 compspec_dispose (lastcs);
1658
Jari Aaltobb706242000-03-17 21:46:59 +00001659 return (rmatches);
1660}
1661
1662#endif /* PROGRAMMABLE_COMPLETION */