blob: e1ccaac8678ed6cbd3c2b2496fb6ad258954482c [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
Jari Aalto31859422009-01-12 13:36:28 +00003/* Copyright (C) 1999-2009 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
40#include <stdio.h>
41#include "bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000042#include "bashintl.h"
Jari Aaltobb706242000-03-17 21:46:59 +000043
44#include "shell.h"
45#include "pcomplete.h"
46#include "alias.h"
47#include "bashline.h"
Jari Aaltof73dda02001-11-13 17:56:06 +000048#include "execute_cmd.h"
Jari Aaltobb706242000-03-17 21:46:59 +000049#include "pathexp.h"
50
51#if defined (JOB_CONTROL)
52# include "jobs.h"
53#endif
54
55#if !defined (NSIG)
56# include "trap.h"
57#endif
58
59#include "builtins.h"
60#include "builtins/common.h"
61
62#include <glob/glob.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000063#include <glob/strmatch.h>
Jari Aaltobb706242000-03-17 21:46:59 +000064
65#include <readline/rlconf.h>
66#include <readline/readline.h>
67#include <readline/history.h>
68
69#ifdef STRDUP
70# undef STRDUP
71#endif
72#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
73
74typedef SHELL_VAR **SVFUNC ();
75
76#ifndef HAVE_STRPBRK
77extern char *strpbrk __P((char *, char *));
78#endif
79
Jari Aaltobb706242000-03-17 21:46:59 +000080extern int array_needs_making;
81extern STRING_INT_ALIST word_token_alist[];
82extern char *signal_names[];
83
Jari Aalto7117c2d2002-07-17 14:10:11 +000084#if defined (DEBUG)
85#if defined (PREFER_STDARG)
Jari Aaltof73dda02001-11-13 17:56:06 +000086static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
87#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +000088#endif /* DEBUG */
Jari Aaltof73dda02001-11-13 17:56:06 +000089
90static int it_init_joblist __P((ITEMLIST *, int));
91
92static int it_init_aliases __P((ITEMLIST *));
93static int it_init_arrayvars __P((ITEMLIST *));
94static int it_init_bindings __P((ITEMLIST *));
95static int it_init_builtins __P((ITEMLIST *));
96static int it_init_disabled __P((ITEMLIST *));
97static int it_init_enabled __P((ITEMLIST *));
98static int it_init_exported __P((ITEMLIST *));
99static int it_init_functions __P((ITEMLIST *));
100static int it_init_hostnames __P((ITEMLIST *));
101static int it_init_jobs __P((ITEMLIST *));
102static int it_init_running __P((ITEMLIST *));
103static int it_init_stopped __P((ITEMLIST *));
104static int it_init_keywords __P((ITEMLIST *));
105static int it_init_signals __P((ITEMLIST *));
106static int it_init_variables __P((ITEMLIST *));
107static int it_init_setopts __P((ITEMLIST *));
108static int it_init_shopts __P((ITEMLIST *));
109
110static int shouldexp_filterpat __P((char *));
111static char *preproc_filterpat __P((char *, char *));
112
113static void init_itemlist_from_varlist __P((ITEMLIST *, SVFUNC *));
114
115static STRINGLIST *gen_matches_from_itemlist __P((ITEMLIST *, const char *));
116static STRINGLIST *gen_action_completions __P((COMPSPEC *, const char *));
117static STRINGLIST *gen_globpat_matches __P((COMPSPEC *, const char *));
118static STRINGLIST *gen_wordlist_matches __P((COMPSPEC *, const char *));
119static STRINGLIST *gen_shell_function_matches __P((COMPSPEC *, const char *,
120 char *, int, WORD_LIST *,
121 int, int));
122static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *, char *,
123 int, WORD_LIST *, int, int));
124
125static char *pcomp_filename_completion_function __P((const char *, int));
126
127#if defined (ARRAY_VARS)
128static SHELL_VAR *bind_comp_words __P((WORD_LIST *));
129#endif
130static void bind_compfunc_variables __P((char *, int, WORD_LIST *, int, int));
131static void unbind_compfunc_variables __P((int));
132static WORD_LIST *build_arg_list __P((char *, const char *, WORD_LIST *, int));
133static WORD_LIST *command_line_to_word_list __P((char *, int, int, int *, int *));
Jari Aaltobb706242000-03-17 21:46:59 +0000134
Jari Aalto7117c2d2002-07-17 14:10:11 +0000135#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +0000136static int progcomp_debug = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000137#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000138
139int prog_completion_enabled = 1;
140
141/* These are used to manage the arrays of strings for possible completions. */
142ITEMLIST it_aliases = { 0, it_init_aliases, (STRINGLIST *)0 };
143ITEMLIST it_arrayvars = { LIST_DYNAMIC, it_init_arrayvars, (STRINGLIST *)0 };
144ITEMLIST it_bindings = { 0, it_init_bindings, (STRINGLIST *)0 };
145ITEMLIST it_builtins = { 0, it_init_builtins, (STRINGLIST *)0 };
146ITEMLIST it_commands = { LIST_DYNAMIC }; /* unused */
147ITEMLIST it_directories = { LIST_DYNAMIC }; /* unused */
148ITEMLIST it_disabled = { 0, it_init_disabled, (STRINGLIST *)0 };
149ITEMLIST it_enabled = { 0, it_init_enabled, (STRINGLIST *)0 };
150ITEMLIST it_exports = { LIST_DYNAMIC, it_init_exported, (STRINGLIST *)0 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000151ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */
Jari Aaltobb706242000-03-17 21:46:59 +0000152ITEMLIST it_functions = { 0, it_init_functions, (STRINGLIST *)0 };
153ITEMLIST it_hostnames = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000154ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */
Jari Aaltof73dda02001-11-13 17:56:06 +0000155ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 };
Jari Aaltobb706242000-03-17 21:46:59 +0000156ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 };
157ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000158ITEMLIST it_services = { LIST_DYNAMIC }; /* unused */
Jari Aaltobb706242000-03-17 21:46:59 +0000159ITEMLIST it_setopts = { 0, it_init_setopts, (STRINGLIST *)0 };
160ITEMLIST it_shopts = { 0, it_init_shopts, (STRINGLIST *)0 };
161ITEMLIST it_signals = { 0, it_init_signals, (STRINGLIST *)0 };
162ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
Jari Aalto7117c2d2002-07-17 14:10:11 +0000163ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
Jari Aaltobb706242000-03-17 21:46:59 +0000164ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
165
Jari Aalto31859422009-01-12 13:36:28 +0000166COMPSPEC *pcomp_curcs;
167const char *pcomp_curcmd;
168
Jari Aalto7117c2d2002-07-17 14:10:11 +0000169#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +0000170/* Debugging code */
Jari Aaltobb706242000-03-17 21:46:59 +0000171static void
172#if defined (PREFER_STDARG)
173debug_printf (const char *format, ...)
174#else
175debug_printf (format, va_alist)
176 const char *format;
177 va_dcl
178#endif
179{
180 va_list args;
181
182 if (progcomp_debug == 0)
183 return;
184
Jari Aalto7117c2d2002-07-17 14:10:11 +0000185 SH_VA_START (args, format);
Jari Aaltobb706242000-03-17 21:46:59 +0000186
187 fprintf (stdout, "DEBUG: ");
188 vfprintf (stdout, format, args);
189 fprintf (stdout, "\n");
190
191 rl_on_new_line ();
192
193 va_end (args);
194}
Jari Aalto7117c2d2002-07-17 14:10:11 +0000195#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000196
197/* Functions to manage the item lists */
198
199void
200set_itemlist_dirty (it)
201 ITEMLIST *it;
202{
203 it->flags |= LIST_DIRTY;
204}
205
206void
207initialize_itemlist (itp)
208 ITEMLIST *itp;
209{
210 (*itp->list_getter) (itp);
211 itp->flags |= LIST_INITIALIZED;
212 itp->flags &= ~LIST_DIRTY;
213}
214
215void
216clean_itemlist (itp)
217 ITEMLIST *itp;
218{
219 STRINGLIST *sl;
220
221 sl = itp->slist;
222 if (sl)
223 {
224 if ((itp->flags & (LIST_DONTFREEMEMBERS|LIST_DONTFREE)) == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000225 strvec_flush (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000226 if ((itp->flags & LIST_DONTFREE) == 0)
227 free (sl->list);
228 free (sl);
229 }
230 itp->slist = (STRINGLIST *)NULL;
231 itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY);
232}
233
Jari Aaltobb706242000-03-17 21:46:59 +0000234
235static int
236shouldexp_filterpat (s)
237 char *s;
238{
239 register char *p;
240
241 for (p = s; p && *p; p++)
242 {
243 if (*p == '\\')
244 p++;
245 else if (*p == '&')
246 return 1;
247 }
248 return 0;
249}
250
251/* Replace any instance of `&' in PAT with TEXT. Backslash may be used to
252 quote a `&' and inhibit substitution. Returns a new string. This just
253 calls stringlib.c:strcreplace(). */
254static char *
255preproc_filterpat (pat, text)
256 char *pat;
257 char *text;
258{
259 char *ret;
260
261 ret = strcreplace (pat, '&', text, 1);
262 return ret;
263}
264
265/* Remove any match of FILTERPAT from SL. A `&' in FILTERPAT is replaced by
266 TEXT. A leading `!' in FILTERPAT negates the pattern; in this case
267 any member of SL->list that does *not* match will be removed. This returns
268 a new STRINGLIST with the matching members of SL *copied*. Any
269 non-matching members of SL->list are *freed*. */
270STRINGLIST *
271filter_stringlist (sl, filterpat, text)
272 STRINGLIST *sl;
273 char *filterpat, *text;
274{
275 int i, m, not;
276 STRINGLIST *ret;
277 char *npat, *t;
278
279 if (sl == 0 || sl->list == 0 || sl->list_len == 0)
280 return sl;
281
282 npat = shouldexp_filterpat (filterpat) ? preproc_filterpat (filterpat, text) : filterpat;
283
284 not = (npat[0] == '!');
285 t = not ? npat + 1 : npat;
286
Jari Aalto7117c2d2002-07-17 14:10:11 +0000287 ret = strlist_create (sl->list_size);
Jari Aaltobb706242000-03-17 21:46:59 +0000288 for (i = 0; i < sl->list_len; i++)
289 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000290 m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);
Jari Aaltobb706242000-03-17 21:46:59 +0000291 if ((not && m == FNM_NOMATCH) || (not == 0 && m != FNM_NOMATCH))
292 free (sl->list[i]);
293 else
294 ret->list[ret->list_len++] = sl->list[i];
295 }
296
297 ret->list[ret->list_len] = (char *)NULL;
298 if (npat != filterpat)
299 free (npat);
300
301 return ret;
302}
303
Jari Aalto28ef6c32001-04-06 19:14:31 +0000304/* Turn an array of strings returned by rl_completion_matches into a STRINGLIST.
305 This understands how rl_completion_matches sets matches[0] (the lcd of the
Jari Aaltobb706242000-03-17 21:46:59 +0000306 strings in the list, unless it's the only match). */
307STRINGLIST *
308completions_to_stringlist (matches)
309 char **matches;
310{
311 STRINGLIST *sl;
312 int mlen, i, n;
313
Jari Aalto7117c2d2002-07-17 14:10:11 +0000314 mlen = (matches == 0) ? 0 : strvec_len (matches);
315 sl = strlist_create (mlen + 1);
Jari Aaltobb706242000-03-17 21:46:59 +0000316
317 if (matches == 0 || matches[0] == 0)
318 return sl;
319
320 if (matches[1] == 0)
321 {
322 sl->list[0] = STRDUP (matches[0]);
323 sl->list[sl->list_len = 1] = (char *)NULL;
324 return sl;
325 }
326
327 for (i = 1, n = 0; i < mlen; i++, n++)
328 sl->list[n] = STRDUP (matches[i]);
329 sl->list_len = n;
330 sl->list[n] = (char *)NULL;
331
332 return sl;
333}
334
335/* Functions to manage the various ITEMLISTs that we populate internally.
336 The caller is responsible for setting ITP->flags correctly. */
337
338static int
339it_init_aliases (itp)
340 ITEMLIST *itp;
341{
342#ifdef ALIAS
Jari Aaltof73dda02001-11-13 17:56:06 +0000343 alias_t **alias_list;
Jari Aaltobb706242000-03-17 21:46:59 +0000344 register int i, n;
345 STRINGLIST *sl;
346
Jari Aaltof73dda02001-11-13 17:56:06 +0000347 alias_list = all_aliases ();
348 if (alias_list == 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000349 {
350 itp->slist = (STRINGLIST *)NULL;
351 return 0;
352 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000353 for (n = 0; alias_list[n]; n++)
Jari Aaltobb706242000-03-17 21:46:59 +0000354 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000355 sl = strlist_create (n+1);
Jari Aaltobb706242000-03-17 21:46:59 +0000356 for (i = 0; i < n; i++)
Jari Aaltof73dda02001-11-13 17:56:06 +0000357 sl->list[i] = STRDUP (alias_list[i]->name);
Jari Aaltobb706242000-03-17 21:46:59 +0000358 sl->list[n] = (char *)NULL;
359 sl->list_size = sl->list_len = n;
360 itp->slist = sl;
361#else
362 itp->slist = (STRINGLIST *)NULL;
363#endif
364 return 1;
365}
366
367static void
368init_itemlist_from_varlist (itp, svfunc)
369 ITEMLIST *itp;
370 SVFUNC *svfunc;
371{
372 SHELL_VAR **vlist;
373 STRINGLIST *sl;
374 register int i, n;
375
376 vlist = (*svfunc) ();
Jari Aaltob80f6442004-07-27 13:29:18 +0000377 if (vlist == 0)
378 {
379 itp->slist = (STRINGLIST *)NULL;
380 return;
381 }
Jari Aaltobb706242000-03-17 21:46:59 +0000382 for (n = 0; vlist[n]; n++)
383 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000384 sl = strlist_create (n+1);
Jari Aaltobb706242000-03-17 21:46:59 +0000385 for (i = 0; i < n; i++)
386 sl->list[i] = savestring (vlist[i]->name);
387 sl->list[sl->list_len = n] = (char *)NULL;
388 itp->slist = sl;
389}
390
391static int
392it_init_arrayvars (itp)
393 ITEMLIST *itp;
394{
395#if defined (ARRAY_VARS)
396 init_itemlist_from_varlist (itp, all_array_variables);
397 return 1;
398#else
399 return 0;
400#endif
401}
402
403static int
404it_init_bindings (itp)
405 ITEMLIST *itp;
406{
407 char **blist;
408 STRINGLIST *sl;
409
410 /* rl_funmap_names allocates blist, but not its members */
Jari Aaltof73dda02001-11-13 17:56:06 +0000411 blist = (char **)rl_funmap_names (); /* XXX fix const later */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000412 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000413 sl->list = blist;
414 sl->list_size = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000415 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000416 itp->flags |= LIST_DONTFREEMEMBERS;
417 itp->slist = sl;
418
419 return 0;
420}
421
422static int
423it_init_builtins (itp)
424 ITEMLIST *itp;
425{
426 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000427 register int i, n;
428
Jari Aalto7117c2d2002-07-17 14:10:11 +0000429 sl = strlist_create (num_shell_builtins);
Jari Aaltobb706242000-03-17 21:46:59 +0000430 for (i = n = 0; i < num_shell_builtins; i++)
431 if (shell_builtins[i].function)
432 sl->list[n++] = shell_builtins[i].name;
433 sl->list[sl->list_len = n] = (char *)NULL;
434 itp->flags |= LIST_DONTFREEMEMBERS;
435 itp->slist = sl;
436 return 0;
437}
438
439static int
440it_init_enabled (itp)
441 ITEMLIST *itp;
442{
443 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000444 register int i, n;
445
Jari Aalto7117c2d2002-07-17 14:10:11 +0000446 sl = strlist_create (num_shell_builtins);
Jari Aaltobb706242000-03-17 21:46:59 +0000447 for (i = n = 0; i < num_shell_builtins; i++)
448 {
449 if (shell_builtins[i].function && (shell_builtins[i].flags & BUILTIN_ENABLED))
450 sl->list[n++] = shell_builtins[i].name;
451 }
452 sl->list[sl->list_len = n] = (char *)NULL;
453 itp->flags |= LIST_DONTFREEMEMBERS;
454 itp->slist = sl;
455 return 0;
456}
457
458static int
459it_init_disabled (itp)
460 ITEMLIST *itp;
461{
462 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000463 register int i, n;
464
Jari Aalto7117c2d2002-07-17 14:10:11 +0000465 sl = strlist_create (num_shell_builtins);
Jari Aaltobb706242000-03-17 21:46:59 +0000466 for (i = n = 0; i < num_shell_builtins; i++)
467 {
468 if (shell_builtins[i].function && ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
469 sl->list[n++] = shell_builtins[i].name;
470 }
471 sl->list[sl->list_len = n] = (char *)NULL;
472 itp->flags |= LIST_DONTFREEMEMBERS;
473 itp->slist = sl;
474 return 0;
475}
476
477static int
478it_init_exported (itp)
479 ITEMLIST *itp;
480{
481 init_itemlist_from_varlist (itp, all_exported_variables);
482 return 0;
483}
484
485static int
486it_init_functions (itp)
487 ITEMLIST *itp;
488{
489 init_itemlist_from_varlist (itp, all_visible_functions);
490 return 0;
491}
492
493static int
494it_init_hostnames (itp)
495 ITEMLIST *itp;
496{
497 STRINGLIST *sl;
498
Jari Aalto7117c2d2002-07-17 14:10:11 +0000499 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000500 sl->list = get_hostname_list ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000501 sl->list_len = sl->list ? strvec_len (sl->list) : 0;
Jari Aaltobb706242000-03-17 21:46:59 +0000502 sl->list_size = sl->list_len;
503 itp->slist = sl;
504 itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE;
505 return 0;
506}
507
508static int
509it_init_joblist (itp, jstate)
510 ITEMLIST *itp;
511 int jstate;
512{
513#if defined (JOB_CONTROL)
514 STRINGLIST *sl;
Jari Aaltof73dda02001-11-13 17:56:06 +0000515 register int i;
Jari Aaltobb706242000-03-17 21:46:59 +0000516 register PROCESS *p;
517 char *s, *t;
Jari Aalto95732b42005-12-07 14:08:12 +0000518 JOB *j;
519 JOB_STATE ws; /* wanted state */
Jari Aaltobb706242000-03-17 21:46:59 +0000520
Jari Aalto31859422009-01-12 13:36:28 +0000521 ws = JNONE;
Jari Aaltobb706242000-03-17 21:46:59 +0000522 if (jstate == 0)
Jari Aalto95732b42005-12-07 14:08:12 +0000523 ws = JRUNNING;
Jari Aaltobb706242000-03-17 21:46:59 +0000524 else if (jstate == 1)
Jari Aalto95732b42005-12-07 14:08:12 +0000525 ws = JSTOPPED;
Jari Aaltobb706242000-03-17 21:46:59 +0000526
Jari Aalto95732b42005-12-07 14:08:12 +0000527 sl = strlist_create (js.j_jobslots);
528 for (i = js.j_jobslots - 1; i >= 0; i--)
Jari Aaltobb706242000-03-17 21:46:59 +0000529 {
Jari Aalto95732b42005-12-07 14:08:12 +0000530 j = get_job_by_jid (i);
531 if (j == 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000532 continue;
Jari Aalto95732b42005-12-07 14:08:12 +0000533 p = j->pipe;
534 if (jstate == -1 || JOBSTATE(i) == ws)
Jari Aaltobb706242000-03-17 21:46:59 +0000535 {
536 s = savestring (p->command);
537 t = strpbrk (s, " \t\n");
538 if (t)
539 *t = '\0';
Jari Aalto28ef6c32001-04-06 19:14:31 +0000540 sl->list[sl->list_len++] = s;
Jari Aaltobb706242000-03-17 21:46:59 +0000541 }
542 }
543 itp->slist = sl;
544#else
545 itp->slist = (STRINGLIST *)NULL;
546#endif
547 return 0;
548}
549
550static int
551it_init_jobs (itp)
552 ITEMLIST *itp;
553{
554 return (it_init_joblist (itp, -1));
555}
556
557static int
558it_init_running (itp)
559 ITEMLIST *itp;
560{
561 return (it_init_joblist (itp, 0));
562}
563
564static int
565it_init_stopped (itp)
566 ITEMLIST *itp;
567{
568 return (it_init_joblist (itp, 1));
569}
570
571static int
572it_init_keywords (itp)
573 ITEMLIST *itp;
574{
575 STRINGLIST *sl;
576 register int i, n;
577
578 for (n = 0; word_token_alist[n].word; n++)
579 ;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000580 sl = strlist_create (n);
Jari Aaltobb706242000-03-17 21:46:59 +0000581 for (i = 0; i < n; i++)
582 sl->list[i] = word_token_alist[i].word;
583 sl->list[sl->list_len = i] = (char *)NULL;
584 itp->flags |= LIST_DONTFREEMEMBERS;
585 itp->slist = sl;
586 return 0;
587}
588
589static int
590it_init_signals (itp)
591 ITEMLIST *itp;
592{
593 STRINGLIST *sl;
594
Jari Aalto7117c2d2002-07-17 14:10:11 +0000595 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000596 sl->list = signal_names;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000597 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000598 itp->flags |= LIST_DONTFREE;
599 itp->slist = sl;
600 return 0;
601}
602
603static int
604it_init_variables (itp)
605 ITEMLIST *itp;
606{
607 init_itemlist_from_varlist (itp, all_visible_variables);
608 return 0;
609}
610
611static int
612it_init_setopts (itp)
613 ITEMLIST *itp;
614{
615 STRINGLIST *sl;
616
Jari Aalto7117c2d2002-07-17 14:10:11 +0000617 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000618 sl->list = get_minus_o_opts ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000619 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000620 itp->slist = sl;
621 itp->flags |= LIST_DONTFREEMEMBERS;
622 return 0;
623}
624
625static int
626it_init_shopts (itp)
627 ITEMLIST *itp;
628{
629 STRINGLIST *sl;
630
Jari Aalto7117c2d2002-07-17 14:10:11 +0000631 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +0000632 sl->list = get_shopt_options ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000633 sl->list_len = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000634 itp->slist = sl;
635 itp->flags |= LIST_DONTFREEMEMBERS;
636 return 0;
637}
638
639/* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
640 as the list of possibilities. If the itemlist has been marked dirty or
641 it should be regenerated every time, destroy the old STRINGLIST and make a
Jari Aaltob80f6442004-07-27 13:29:18 +0000642 new one before trying the match. TEXT is dequoted before attempting a
643 match. */
Jari Aaltobb706242000-03-17 21:46:59 +0000644static STRINGLIST *
645gen_matches_from_itemlist (itp, text)
646 ITEMLIST *itp;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000647 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000648{
649 STRINGLIST *ret, *sl;
650 int tlen, i, n;
Jari Aaltob80f6442004-07-27 13:29:18 +0000651 char *ntxt;
Jari Aaltobb706242000-03-17 21:46:59 +0000652
653 if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
654 (itp->flags & LIST_INITIALIZED) == 0)
655 {
656 if (itp->flags & (LIST_DIRTY | LIST_DYNAMIC))
657 clean_itemlist (itp);
658 if ((itp->flags & LIST_INITIALIZED) == 0)
659 initialize_itemlist (itp);
660 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000661 if (itp->slist == 0)
662 return ((STRINGLIST *)NULL);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000663 ret = strlist_create (itp->slist->list_len+1);
Jari Aaltobb706242000-03-17 21:46:59 +0000664 sl = itp->slist;
Jari Aaltob80f6442004-07-27 13:29:18 +0000665
666 ntxt = bash_dequote_text (text);
667 tlen = STRLEN (ntxt);
668
Jari Aaltobb706242000-03-17 21:46:59 +0000669 for (i = n = 0; i < sl->list_len; i++)
670 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000671 if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
Jari Aaltobb706242000-03-17 21:46:59 +0000672 ret->list[n++] = STRDUP (sl->list[i]);
673 }
674 ret->list[ret->list_len = n] = (char *)NULL;
Jari Aaltob80f6442004-07-27 13:29:18 +0000675
676 FREE (ntxt);
Jari Aaltobb706242000-03-17 21:46:59 +0000677 return ret;
678}
679
Jari Aalto28ef6c32001-04-06 19:14:31 +0000680/* A wrapper for rl_filename_completion_function that dequotes the filename
Jari Aaltobb706242000-03-17 21:46:59 +0000681 before attempting completions. */
682static char *
683pcomp_filename_completion_function (text, state)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000684 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000685 int state;
686{
687 static char *dfn; /* dequoted filename */
688 int qc;
689
690 if (state == 0)
691 {
692 FREE (dfn);
693 /* remove backslashes quoting special characters in filenames. */
Jari Aalto31859422009-01-12 13:36:28 +0000694#if 1
695 if (RL_ISSTATE (RL_STATE_COMPLETING) && rl_filename_dequoting_function)
Jari Aaltob80f6442004-07-27 13:29:18 +0000696#else
Jari Aalto31859422009-01-12 13:36:28 +0000697 if (rl_filename_dequoting_function)
698#endif
699 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000700 /* Use rl_completion_quote_character because any single or
701 double quotes have been removed by the time TEXT makes it
702 here, and we don't want to remove backslashes inside
703 quoted strings. */
Jari Aalto31859422009-01-12 13:36:28 +0000704 dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
Jari Aaltobb706242000-03-17 21:46:59 +0000705 }
706 else
707 dfn = savestring (text);
708 }
709
Jari Aalto28ef6c32001-04-06 19:14:31 +0000710 return (rl_filename_completion_function (dfn, state));
Jari Aaltobb706242000-03-17 21:46:59 +0000711}
712
713#define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
714 do { \
715 if (bmap & flag) \
716 { \
717 tlist = gen_matches_from_itemlist (it, text); \
Jari Aaltof73dda02001-11-13 17:56:06 +0000718 if (tlist) \
719 { \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000720 glist = strlist_append (glist, tlist); \
721 strlist_dispose (tlist); \
Jari Aaltof73dda02001-11-13 17:56:06 +0000722 } \
Jari Aaltobb706242000-03-17 21:46:59 +0000723 } \
724 } while (0)
725
726#define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
727 do { \
728 if (bmap & flag) \
729 { \
Jari Aalto28ef6c32001-04-06 19:14:31 +0000730 cmatches = rl_completion_matches (text, func); \
Jari Aaltobb706242000-03-17 21:46:59 +0000731 tlist = completions_to_stringlist (cmatches); \
Jari Aalto7117c2d2002-07-17 14:10:11 +0000732 glist = strlist_append (glist, tlist); \
733 strvec_dispose (cmatches); \
734 strlist_dispose (tlist); \
Jari Aaltobb706242000-03-17 21:46:59 +0000735 } \
736 } while (0)
737
738/* Functions to generate lists of matches from the actions member of CS. */
739
740static STRINGLIST *
741gen_action_completions (cs, text)
742 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000743 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000744{
745 STRINGLIST *ret, *tmatches;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000746 char **cmatches; /* from rl_completion_matches ... */
Jari Aaltobb706242000-03-17 21:46:59 +0000747 unsigned long flags;
748
749 ret = tmatches = (STRINGLIST *)NULL;
750 flags = cs->actions;
751
752 GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches);
753 GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches);
754 GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches);
755 GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches);
756 GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches);
757 GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches);
758 GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches);
759 GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches);
760 GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches);
761 GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches);
762 GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches);
763 GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches);
764 GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches);
765 GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches);
766 GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches);
767 GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches);
768 GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches);
769
770 GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches);
771 GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000772 GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
Jari Aaltof73dda02001-11-13 17:56:06 +0000773 GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000774 GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +0000775
776 /* And lastly, the special case for directories */
777 if (flags & CA_DIRECTORY)
778 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000779 rl_completion_mark_symlink_dirs = 1; /* override user preference */
Jari Aaltobb706242000-03-17 21:46:59 +0000780 cmatches = bash_directory_completion_matches (text);
781 tmatches = completions_to_stringlist (cmatches);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000782 ret = strlist_append (ret, tmatches);
783 strvec_dispose (cmatches);
784 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +0000785 }
786
787 return ret;
788}
789
790/* Generate a list of matches for CS->globpat. Unresolved: should this use
791 TEXT as a match prefix, or just go without? Currently, the code does not
792 use TEXT, just globs CS->globpat and returns the results. If we do decide
793 to use TEXT, we should call quote_string_for_globbing before the call to
794 glob_filename. */
795static STRINGLIST *
796gen_globpat_matches (cs, text)
797 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000798 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000799{
800 STRINGLIST *sl;
Jari Aaltobb706242000-03-17 21:46:59 +0000801
Jari Aalto7117c2d2002-07-17 14:10:11 +0000802 sl = strlist_create (0);
803 sl->list = glob_filename (cs->globpat, 0);
Jari Aaltobb706242000-03-17 21:46:59 +0000804 if (GLOB_FAILED (sl->list))
805 sl->list = (char **)NULL;
806 if (sl->list)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000807 sl->list_len = sl->list_size = strvec_len (sl->list);
Jari Aaltobb706242000-03-17 21:46:59 +0000808 return sl;
809}
810
811/* Perform the shell word expansions on CS->words and return the results.
812 Again, this ignores TEXT. */
813static STRINGLIST *
814gen_wordlist_matches (cs, text)
815 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000816 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000817{
818 WORD_LIST *l, *l2;
819 STRINGLIST *sl;
Jari Aalto06285672006-10-10 14:15:34 +0000820 int nw, tlen;
Jari Aaltob80f6442004-07-27 13:29:18 +0000821 char *ntxt; /* dequoted TEXT to use in comparisons */
Jari Aaltobb706242000-03-17 21:46:59 +0000822
823 if (cs->words == 0 || cs->words[0] == '\0')
824 return ((STRINGLIST *)NULL);
825
826 /* This used to be a simple expand_string(cs->words, 0), but that won't
827 do -- there's no way to split a simple list into individual words
828 that way, since the shell semantics say that word splitting is done
829 only on the results of expansion. */
830 l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, (int *)NULL, (int *)NULL);
831 if (l == 0)
832 return ((STRINGLIST *)NULL);
833 /* This will jump back to the top level if the expansion fails... */
834 l2 = expand_words_shellexp (l);
835 dispose_words (l);
836
837 nw = list_length (l2);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000838 sl = strlist_create (nw + 1);
Jari Aaltob80f6442004-07-27 13:29:18 +0000839
840 ntxt = bash_dequote_text (text);
841 tlen = STRLEN (ntxt);
Jari Aaltobb706242000-03-17 21:46:59 +0000842
843 for (nw = 0, l = l2; l; l = l->next)
844 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000845 if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
Jari Aalto28ef6c32001-04-06 19:14:31 +0000846 sl->list[nw++] = STRDUP (l->word->word);
Jari Aaltobb706242000-03-17 21:46:59 +0000847 }
848 sl->list[sl->list_len = nw] = (char *)NULL;
849
Jari Aalto95732b42005-12-07 14:08:12 +0000850 dispose_words (l2);
Jari Aaltob80f6442004-07-27 13:29:18 +0000851 FREE (ntxt);
Jari Aaltobb706242000-03-17 21:46:59 +0000852 return sl;
853}
854
855#ifdef ARRAY_VARS
856
857static SHELL_VAR *
858bind_comp_words (lwords)
859 WORD_LIST *lwords;
860{
861 SHELL_VAR *v;
862
863 v = find_variable ("COMP_WORDS");
864 if (v == 0)
865 v = make_new_array_variable ("COMP_WORDS");
866 if (readonly_p (v))
867 VUNSETATTR (v, att_readonly);
868 if (array_p (v) == 0)
869 v = convert_var_to_array (v);
Jari Aalto95732b42005-12-07 14:08:12 +0000870 v = assign_array_var_from_word_list (v, lwords, 0);
Jari Aaltoeb873672004-11-09 21:37:25 +0000871
872 VUNSETATTR (v, att_invisible);
Jari Aaltobb706242000-03-17 21:46:59 +0000873 return v;
874}
875#endif /* ARRAY_VARS */
876
877static void
878bind_compfunc_variables (line, ind, lwords, cw, exported)
879 char *line;
880 int ind;
881 WORD_LIST *lwords;
882 int cw, exported;
883{
Jari Aaltof73dda02001-11-13 17:56:06 +0000884 char ibuf[INT_STRLEN_BOUND(int) + 1];
Jari Aaltobb706242000-03-17 21:46:59 +0000885 char *value;
886 SHELL_VAR *v;
887
888 /* Set the variables that the function expects while it executes. Maybe
889 these should be in the function environment (temporary_env). */
Jari Aalto95732b42005-12-07 14:08:12 +0000890 v = bind_variable ("COMP_LINE", line, 0);
Jari Aaltobb706242000-03-17 21:46:59 +0000891 if (v && exported)
892 VSETATTR(v, att_exported);
893
Jari Aaltof73dda02001-11-13 17:56:06 +0000894 value = inttostr (ind, ibuf, sizeof(ibuf));
Jari Aaltobb706242000-03-17 21:46:59 +0000895 v = bind_int_variable ("COMP_POINT", value);
896 if (v && exported)
897 VSETATTR(v, att_exported);
898
Jari Aalto31859422009-01-12 13:36:28 +0000899 value = inttostr (rl_completion_type, ibuf, sizeof (ibuf));
900 v = bind_int_variable ("COMP_TYPE", value);
901 if (v && exported)
902 VSETATTR(v, att_exported);
903
904 value = inttostr (rl_completion_invoking_key, ibuf, sizeof (ibuf));
905 v = bind_int_variable ("COMP_KEY", value);
906 if (v && exported)
907 VSETATTR(v, att_exported);
908
Jari Aaltobb706242000-03-17 21:46:59 +0000909 /* Since array variables can't be exported, we don't bother making the
910 array of words. */
911 if (exported == 0)
912 {
913#ifdef ARRAY_VARS
914 v = bind_comp_words (lwords);
Jari Aaltof73dda02001-11-13 17:56:06 +0000915 value = inttostr (cw, ibuf, sizeof(ibuf));
Jari Aaltobb706242000-03-17 21:46:59 +0000916 bind_int_variable ("COMP_CWORD", value);
917#endif
918 }
919 else
920 array_needs_making = 1;
921}
922
923static void
924unbind_compfunc_variables (exported)
925 int exported;
926{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000927 unbind_variable ("COMP_LINE");
928 unbind_variable ("COMP_POINT");
Jari Aalto31859422009-01-12 13:36:28 +0000929 unbind_variable ("COMP_TYPE");
930 unbind_variable ("COMP_KEY");
Jari Aaltobb706242000-03-17 21:46:59 +0000931#ifdef ARRAY_VARS
Jari Aalto7117c2d2002-07-17 14:10:11 +0000932 unbind_variable ("COMP_WORDS");
933 unbind_variable ("COMP_CWORD");
Jari Aaltobb706242000-03-17 21:46:59 +0000934#endif
935 if (exported)
936 array_needs_making = 1;
937}
938
939/* Build the list of words to pass to a function or external command
940 as arguments. When the function or command is invoked,
941
942 $0 == function or command being invoked
943 $1 == command name
Jari Aalto17345e52009-02-19 22:21:29 +0000944 $2 == word to be completed (possibly null)
945 $3 == previous word
Jari Aaltobb706242000-03-17 21:46:59 +0000946
947 Functions can access all of the words in the current command line
Jari Aalto17345e52009-02-19 22:21:29 +0000948 with the COMP_WORDS array. External commands cannot; they have to
949 make do with the COMP_LINE and COMP_POINT variables. */
Jari Aaltobb706242000-03-17 21:46:59 +0000950
951static WORD_LIST *
952build_arg_list (cmd, text, lwords, ind)
953 char *cmd;
Jari Aaltof73dda02001-11-13 17:56:06 +0000954 const char *text;
Jari Aaltobb706242000-03-17 21:46:59 +0000955 WORD_LIST *lwords;
956 int ind;
957{
958 WORD_LIST *ret, *cl, *l;
959 WORD_DESC *w;
960 int i;
961
962 ret = (WORD_LIST *)NULL;
963 w = make_word (cmd);
964 ret = make_word_list (w, (WORD_LIST *)NULL);
965
966 w = (lwords && lwords->word) ? copy_word (lwords->word) : make_word ("");
967 cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
968
969 w = make_word (text);
970 cl->next = make_word_list (w, (WORD_LIST *)NULL);
971 cl = cl->next;
972
973 /* Search lwords for current word */
974 for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++)
975 ;
976 w = (l && l->word) ? copy_word (l->word) : make_word ("");
977 cl->next = make_word_list (w, (WORD_LIST *)NULL);
978
979 return ret;
980}
981
982/* Build a command string with
983 $0 == cs->funcname (function to execute for completion list)
984 $1 == command name (command being completed)
985 $2 = word to be completed (possibly null)
986 $3 = previous word
987 and run in the current shell. The function should put its completion
988 list into the array variable COMPREPLY. We build a STRINGLIST
989 from the results and return it.
990
991 Since the shell function should return its list of matches in an array
992 variable, this does nothing if arrays are not compiled into the shell. */
993
994static STRINGLIST *
995gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
996 COMPSPEC *cs;
Jari Aaltof73dda02001-11-13 17:56:06 +0000997 const char *text;
998 char *line;
Jari Aaltobb706242000-03-17 21:46:59 +0000999 int ind;
1000 WORD_LIST *lwords;
1001 int nw, cw;
1002{
1003 char *funcname;
1004 STRINGLIST *sl;
1005 SHELL_VAR *f, *v;
1006 WORD_LIST *cmdlist;
1007 int fval;
Jari Aalto95732b42005-12-07 14:08:12 +00001008 sh_parser_state_t ps;
Jari Aalto17345e52009-02-19 22:21:29 +00001009 sh_parser_state_t * restrict pps;
Jari Aaltobb706242000-03-17 21:46:59 +00001010#if defined (ARRAY_VARS)
1011 ARRAY *a;
1012#endif
1013
1014 funcname = cs->funcname;
1015 f = find_function (funcname);
1016 if (f == 0)
1017 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001018 internal_error (_("completion: function `%s' not found"), funcname);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001019 rl_ding ();
Jari Aaltobb706242000-03-17 21:46:59 +00001020 rl_on_new_line ();
1021 return ((STRINGLIST *)NULL);
1022 }
1023
1024#if !defined (ARRAY_VARS)
1025 return ((STRINGLIST *)NULL);
1026#else
1027
1028 /* We pass cw - 1 because command_line_to_word_list returns indices that are
1029 1-based, while bash arrays are 0-based. */
1030 bind_compfunc_variables (line, ind, lwords, cw - 1, 0);
1031
1032 cmdlist = build_arg_list (funcname, text, lwords, cw);
Jari Aalto95732b42005-12-07 14:08:12 +00001033
Jari Aalto17345e52009-02-19 22:21:29 +00001034 pps = &ps;
1035 begin_unwind_frame ("gen-shell-function-matches");
1036 add_unwind_protect (restore_parser_state, (char *)pps);
1037 add_unwind_protect (dispose_words, (char *)cmdlist);
1038 add_unwind_protect (unbind_compfunc_variables, (char *)0);
1039
Jari Aaltobb706242000-03-17 21:46:59 +00001040 fval = execute_shell_function (f, cmdlist);
Jari Aalto17345e52009-02-19 22:21:29 +00001041
1042 discard_unwind_frame ("gen-shell-function-matches");
1043 restore_parser_state (pps);
Jari Aaltobb706242000-03-17 21:46:59 +00001044
1045 /* Now clean up and destroy everything. */
1046 dispose_words (cmdlist);
1047 unbind_compfunc_variables (0);
1048
1049 /* The list of completions is returned in the array variable COMPREPLY. */
1050 v = find_variable ("COMPREPLY");
1051 if (v == 0)
1052 return ((STRINGLIST *)NULL);
1053 if (array_p (v) == 0)
1054 v = convert_var_to_array (v);
1055
Jari Aaltoeb873672004-11-09 21:37:25 +00001056 VUNSETATTR (v, att_invisible);
1057
Jari Aaltobb706242000-03-17 21:46:59 +00001058 a = array_cell (v);
1059 if (a == 0 || array_empty (a))
1060 sl = (STRINGLIST *)NULL;
1061 else
1062 {
1063 /* XXX - should we filter the list of completions so only those matching
1064 TEXT are returned? Right now, we do not. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001065 sl = strlist_create (0);
Jari Aaltobb706242000-03-17 21:46:59 +00001066 sl->list = array_to_argv (a);
1067 sl->list_len = sl->list_size = array_num_elements (a);
1068 }
1069
1070 /* XXX - should we unbind COMPREPLY here? */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001071 unbind_variable ("COMPREPLY");
Jari Aaltobb706242000-03-17 21:46:59 +00001072
1073 return (sl);
1074#endif
1075}
1076
1077/* Build a command string with
1078 $0 == cs->command (command to execute for completion list)
1079 $1 == command name (command being completed)
1080 $2 = word to be completed (possibly null)
1081 $3 = previous word
1082 and run in with command substitution. Parse the results, one word
1083 per line, with backslashes allowed to escape newlines. Build a
1084 STRINGLIST from the results and return it. */
1085
1086static STRINGLIST *
1087gen_command_matches (cs, text, line, ind, lwords, nw, cw)
1088 COMPSPEC *cs;
Jari Aaltof73dda02001-11-13 17:56:06 +00001089 const char *text;
1090 char *line;
Jari Aaltobb706242000-03-17 21:46:59 +00001091 int ind;
1092 WORD_LIST *lwords;
1093 int nw, cw;
1094{
1095 char *csbuf, *cscmd, *t;
1096 int cmdlen, cmdsize, n, ws, we;
1097 WORD_LIST *cmdlist, *cl;
Jari Aalto31859422009-01-12 13:36:28 +00001098 WORD_DESC *tw;
Jari Aaltobb706242000-03-17 21:46:59 +00001099 STRINGLIST *sl;
1100
1101 bind_compfunc_variables (line, ind, lwords, cw, 1);
1102 cmdlist = build_arg_list (cs->command, text, lwords, cw);
1103
1104 /* Estimate the size needed for the buffer. */
1105 n = strlen (cs->command);
1106 cmdsize = n + 1;
1107 for (cl = cmdlist->next; cl; cl = cl->next)
1108 cmdsize += STRLEN (cl->word->word) + 3;
1109 cmdsize += 2;
1110
1111 /* allocate the string for the command and fill it in. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001112 cscmd = (char *)xmalloc (cmdsize + 1);
Jari Aaltobb706242000-03-17 21:46:59 +00001113
1114 strcpy (cscmd, cs->command); /* $0 */
1115 cmdlen = n;
1116 cscmd[cmdlen++] = ' ';
1117 for (cl = cmdlist->next; cl; cl = cl->next) /* $1, $2, $3, ... */
1118 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00001119 t = sh_single_quote (cl->word->word ? cl->word->word : "");
Jari Aaltobb706242000-03-17 21:46:59 +00001120 n = strlen (t);
1121 RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64);
1122 strcpy (cscmd + cmdlen, t);
1123 cmdlen += n;
1124 if (cl->next)
1125 cscmd[cmdlen++] = ' ';
1126 free (t);
1127 }
1128 cscmd[cmdlen] = '\0';
1129
Jari Aalto31859422009-01-12 13:36:28 +00001130 tw = command_substitute (cscmd, 0);
1131 csbuf = tw ? tw->word : (char *)NULL;
1132 dispose_word_desc (tw);
Jari Aaltobb706242000-03-17 21:46:59 +00001133
1134 /* Now clean up and destroy everything. */
1135 dispose_words (cmdlist);
1136 free (cscmd);
1137 unbind_compfunc_variables (1);
1138
1139 if (csbuf == 0 || *csbuf == '\0')
1140 {
1141 FREE (csbuf);
1142 return ((STRINGLIST *)NULL);
1143 }
1144
1145 /* Now break CSBUF up at newlines, with backslash allowed to escape a
1146 newline, and put the individual words into a STRINGLIST. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001147 sl = strlist_create (16);
Jari Aaltobb706242000-03-17 21:46:59 +00001148 for (ws = 0; csbuf[ws]; )
1149 {
1150 we = ws;
1151 while (csbuf[we] && csbuf[we] != '\n')
1152 {
1153 if (csbuf[we] == '\\' && csbuf[we+1] == '\n')
1154 we++;
1155 we++;
1156 }
1157 t = substring (csbuf, ws, we);
1158 if (sl->list_len >= sl->list_size - 1)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001159 strlist_resize (sl, sl->list_size + 16);
Jari Aaltobb706242000-03-17 21:46:59 +00001160 sl->list[sl->list_len++] = t;
1161 while (csbuf[we] == '\n') we++;
1162 ws = we;
1163 }
1164 sl->list[sl->list_len] = (char *)NULL;
1165
1166 free (csbuf);
1167 return (sl);
1168}
1169
1170static WORD_LIST *
1171command_line_to_word_list (line, llen, sentinel, nwp, cwp)
1172 char *line;
1173 int llen, sentinel, *nwp, *cwp;
1174{
1175 WORD_LIST *ret;
1176 char *delims;
1177
Jari Aalto31859422009-01-12 13:36:28 +00001178#if 0
Jari Aaltobb706242000-03-17 21:46:59 +00001179 delims = "()<>;&| \t\n"; /* shell metacharacters break words */
Jari Aalto31859422009-01-12 13:36:28 +00001180#else
1181 delims = rl_completer_word_break_characters;
1182#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001183 ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
1184 return (ret);
1185}
1186
1187/* Evaluate COMPSPEC *cs and return all matches for WORD. */
1188
1189STRINGLIST *
1190gen_compspec_completions (cs, cmd, word, start, end)
1191 COMPSPEC *cs;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001192 const char *cmd;
1193 const char *word;
Jari Aaltobb706242000-03-17 21:46:59 +00001194 int start, end;
1195{
1196 STRINGLIST *ret, *tmatches;
Jari Aaltof73dda02001-11-13 17:56:06 +00001197 char *line;
Jari Aaltobb706242000-03-17 21:46:59 +00001198 int llen, nw, cw;
1199 WORD_LIST *lwords;
Jari Aaltob80f6442004-07-27 13:29:18 +00001200 COMPSPEC *tcs;
Jari Aaltobb706242000-03-17 21:46:59 +00001201
Jari Aalto7117c2d2002-07-17 14:10:11 +00001202#ifdef DEBUG
1203 debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
1204 debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
1205#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001206 ret = gen_action_completions (cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001207#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001208 if (ret && progcomp_debug)
1209 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001210 debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001211 strlist_print (ret, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001212 rl_on_new_line ();
1213 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001214#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001215
1216 /* Now we start generating completions based on the other members of CS. */
1217 if (cs->globpat)
1218 {
1219 tmatches = gen_globpat_matches (cs, word);
1220 if (tmatches)
1221 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001222#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001223 if (progcomp_debug)
1224 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001225 debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001226 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001227 rl_on_new_line ();
1228 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001229#endif
1230 ret = strlist_append (ret, tmatches);
1231 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001232 rl_filename_completion_desired = 1;
1233 }
1234 }
1235
1236 if (cs->words)
1237 {
1238 tmatches = gen_wordlist_matches (cs, word);
1239 if (tmatches)
1240 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001241#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001242 if (progcomp_debug)
1243 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001244 debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001245 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001246 rl_on_new_line ();
1247 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001248#endif
1249 ret = strlist_append (ret, tmatches);
1250 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001251 }
1252 }
1253
1254 lwords = (WORD_LIST *)NULL;
1255 line = (char *)NULL;
1256 if (cs->command || cs->funcname)
1257 {
1258 /* If we have a command or function to execute, we need to first break
1259 the command line into individual words, find the number of words,
1260 and find the word in the list containing the word to be completed. */
1261 line = substring (rl_line_buffer, start, end);
1262 llen = end - start;
1263
Jari Aalto7117c2d2002-07-17 14:10:11 +00001264#ifdef DEBUG
Jari Aaltof73dda02001-11-13 17:56:06 +00001265 debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
Jari Aaltobb706242000-03-17 21:46:59 +00001266 line, llen, rl_point - start, &nw, &cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001267#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001268 lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001269#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001270 if (lwords == 0 && llen > 0)
1271 debug_printf ("ERROR: command_line_to_word_list returns NULL");
1272 else if (progcomp_debug)
1273 {
1274 debug_printf ("command_line_to_word_list -->");
1275 printf ("\t");
1276 print_word_list (lwords, "!");
1277 printf ("\n");
1278 fflush(stdout);
1279 rl_on_new_line ();
1280 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001281#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001282 }
1283
1284 if (cs->funcname)
1285 {
1286 tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1287 if (tmatches)
1288 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001289#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001290 if (progcomp_debug)
1291 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001292 debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001293 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001294 rl_on_new_line ();
1295 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001296#endif
1297 ret = strlist_append (ret, tmatches);
1298 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001299 }
1300 }
1301
1302 if (cs->command)
1303 {
1304 tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
1305 if (tmatches)
1306 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001307#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001308 if (progcomp_debug)
1309 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001310 debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001311 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001312 rl_on_new_line ();
1313 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001314#endif
1315 ret = strlist_append (ret, tmatches);
1316 strlist_dispose (tmatches);
Jari Aaltobb706242000-03-17 21:46:59 +00001317 }
1318 }
1319
1320 if (cs->command || cs->funcname)
1321 {
1322 if (lwords)
1323 dispose_words (lwords);
1324 FREE (line);
1325 }
1326
1327 if (cs->filterpat)
1328 {
1329 tmatches = filter_stringlist (ret, cs->filterpat, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001330#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +00001331 if (progcomp_debug)
1332 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001333 debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001334 strlist_print (tmatches, "\t");
Jari Aaltobb706242000-03-17 21:46:59 +00001335 rl_on_new_line ();
1336 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00001337#endif
Jari Aaltobb706242000-03-17 21:46:59 +00001338 if (ret && ret != tmatches)
1339 {
1340 FREE (ret->list);
1341 free (ret);
1342 }
1343 ret = tmatches;
1344 }
1345
1346 if (cs->prefix || cs->suffix)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001347 ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
Jari Aaltobb706242000-03-17 21:46:59 +00001348
Jari Aalto28ef6c32001-04-06 19:14:31 +00001349 /* If no matches have been generated and the user has specified that
1350 directory completion should be done as a default, call
1351 gen_action_completions again to generate a list of matching directory
1352 names. */
1353 if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
1354 {
Jari Aaltob80f6442004-07-27 13:29:18 +00001355 tcs = compspec_create ();
1356 tcs->actions = CA_DIRECTORY;
1357 ret = gen_action_completions (tcs, word);
1358 compspec_dispose (tcs);
1359 }
1360 else if (cs->options & COPT_PLUSDIRS)
1361 {
1362 tcs = compspec_create ();
1363 tcs->actions = CA_DIRECTORY;
1364 tmatches = gen_action_completions (tcs, word);
1365 ret = strlist_append (ret, tmatches);
1366 strlist_dispose (tmatches);
1367 compspec_dispose (tcs);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001368 }
1369
Jari Aaltobb706242000-03-17 21:46:59 +00001370 return (ret);
1371}
1372
Jari Aalto31859422009-01-12 13:36:28 +00001373void
1374pcomp_set_readline_variables (flags, nval)
1375 int flags, nval;
1376{
1377 /* If the user specified that the compspec returns filenames, make
1378 sure that readline knows it. */
1379 if (flags & COPT_FILENAMES)
1380 rl_filename_completion_desired = nval;
1381 /* If the user doesn't want a space appended, tell readline. */
1382 if (flags & COPT_NOSPACE)
1383 rl_completion_suppress_append = nval;
1384}
1385
1386/* Set or unset FLAGS in the options word of the current compspec.
1387 SET_OR_UNSET is 1 for setting, 0 for unsetting. */
1388void
1389pcomp_set_compspec_options (cs, flags, set_or_unset)
1390 COMPSPEC *cs;
1391 int flags, set_or_unset;
1392{
1393 if (cs == 0 && ((cs = pcomp_curcs) == 0))
1394 return;
1395 if (set_or_unset)
1396 cs->options |= flags;
1397 else
1398 cs->options &= ~flags;
1399}
1400
Jari Aaltobb706242000-03-17 21:46:59 +00001401/* The driver function for the programmable completion code. Returns a list
1402 of matches for WORD, which is an argument to command CMD. START and END
1403 bound the command currently being completed in rl_line_buffer. */
1404char **
1405programmable_completions (cmd, word, start, end, foundp)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001406 const char *cmd;
1407 const char *word;
Jari Aaltobb706242000-03-17 21:46:59 +00001408 int start, end, *foundp;
1409{
Jari Aalto31859422009-01-12 13:36:28 +00001410 COMPSPEC *cs, *oldcs;
Jari Aaltobb706242000-03-17 21:46:59 +00001411 STRINGLIST *ret;
1412 char **rmatches, *t;
Jari Aalto31859422009-01-12 13:36:28 +00001413 const char *oldcmd;
Jari Aaltobb706242000-03-17 21:46:59 +00001414
1415 /* We look at the basename of CMD if the full command does not have
1416 an associated COMPSPEC. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001417 cs = progcomp_search (cmd);
Jari Aaltobb706242000-03-17 21:46:59 +00001418 if (cs == 0)
1419 {
1420 t = strrchr (cmd, '/');
1421 if (t)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001422 cs = progcomp_search (++t);
Jari Aaltobb706242000-03-17 21:46:59 +00001423 }
1424 if (cs == 0)
1425 {
1426 if (foundp)
1427 *foundp = 0;
1428 return ((char **)NULL);
1429 }
1430
Jari Aaltob80f6442004-07-27 13:29:18 +00001431 cs = compspec_copy (cs);
1432
Jari Aalto31859422009-01-12 13:36:28 +00001433 oldcs = pcomp_curcs;
1434 oldcmd = pcomp_curcmd;
1435
1436 pcomp_curcs = cs;
1437 pcomp_curcmd = cmd;
1438
Jari Aalto28ef6c32001-04-06 19:14:31 +00001439 /* Signal the caller that we found a COMPSPEC for this command, and pass
1440 back any meta-options associated with the compspec. */
Jari Aaltobb706242000-03-17 21:46:59 +00001441 if (foundp)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001442 *foundp = 1|cs->options;
Jari Aaltobb706242000-03-17 21:46:59 +00001443
1444 ret = gen_compspec_completions (cs, cmd, word, start, end);
1445
Jari Aalto31859422009-01-12 13:36:28 +00001446 pcomp_curcs = oldcs;
1447 pcomp_curcmd = oldcmd;
1448
Jari Aaltob80f6442004-07-27 13:29:18 +00001449 compspec_dispose (cs);
1450
Jari Aaltobb706242000-03-17 21:46:59 +00001451 if (ret)
1452 {
1453 rmatches = ret->list;
1454 free (ret);
1455 }
1456 else
1457 rmatches = (char **)NULL;
1458
1459 return (rmatches);
1460}
1461
1462#endif /* PROGRAMMABLE_COMPLETION */