]> git.ipfire.org Git - thirdparty/bash.git/blob - pcomplete.c
Bash-4.3 patch 39
[thirdparty/bash.git] / pcomplete.c
1 /* pcomplete.c - functions to generate lists of matches for programmable completion. */
2
3 /* Copyright (C) 1999-2012 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #if defined (PROGRAMMABLE_COMPLETION)
24
25 #include "bashtypes.h"
26 #include "posixstat.h"
27
28 #if defined (HAVE_UNISTD_H)
29 # include <unistd.h>
30 #endif
31
32 #include <signal.h>
33
34 #if defined (PREFER_STDARG)
35 # include <stdarg.h>
36 #else
37 # include <varargs.h>
38 #endif
39
40 #include <sys/time.h>
41
42 #include <stdio.h>
43 #include "bashansi.h"
44 #include "bashintl.h"
45
46 #include "shell.h"
47 #include "pcomplete.h"
48 #include "alias.h"
49 #include "bashline.h"
50 #include "execute_cmd.h"
51 #include "pathexp.h"
52
53 #if defined (JOB_CONTROL)
54 # include "jobs.h"
55 #endif
56
57 #if !defined (NSIG)
58 # include "trap.h"
59 #endif
60
61 #include "shmbutil.h"
62
63 #include "builtins.h"
64 #include "builtins/common.h"
65 #include "builtins/builtext.h"
66
67 #include <glob/glob.h>
68 #include <glob/strmatch.h>
69
70 #include <readline/rlconf.h>
71 #include <readline/readline.h>
72 #include <readline/history.h>
73
74 #define PCOMP_RETRYFAIL 256
75
76 #ifdef STRDUP
77 # undef STRDUP
78 #endif
79 #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
80
81 typedef SHELL_VAR **SVFUNC ();
82
83 #ifndef HAVE_STRPBRK
84 extern char *strpbrk __P((char *, char *));
85 #endif
86
87 extern int array_needs_making;
88 extern STRING_INT_ALIST word_token_alist[];
89 extern char *signal_names[];
90 extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
91
92 #if defined (DEBUG)
93 #if defined (PREFER_STDARG)
94 static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
95 #endif
96 #endif /* DEBUG */
97
98 static int it_init_joblist __P((ITEMLIST *, int));
99
100 static int it_init_aliases __P((ITEMLIST *));
101 static int it_init_arrayvars __P((ITEMLIST *));
102 static int it_init_bindings __P((ITEMLIST *));
103 static int it_init_builtins __P((ITEMLIST *));
104 static int it_init_disabled __P((ITEMLIST *));
105 static int it_init_enabled __P((ITEMLIST *));
106 static int it_init_exported __P((ITEMLIST *));
107 static int it_init_functions __P((ITEMLIST *));
108 static int it_init_helptopics __P((ITEMLIST *));
109 static int it_init_hostnames __P((ITEMLIST *));
110 static int it_init_jobs __P((ITEMLIST *));
111 static int it_init_running __P((ITEMLIST *));
112 static int it_init_stopped __P((ITEMLIST *));
113 static int it_init_keywords __P((ITEMLIST *));
114 static int it_init_signals __P((ITEMLIST *));
115 static int it_init_variables __P((ITEMLIST *));
116 static int it_init_setopts __P((ITEMLIST *));
117 static int it_init_shopts __P((ITEMLIST *));
118
119 static int shouldexp_filterpat __P((char *));
120 static char *preproc_filterpat __P((char *, char *));
121
122 static void init_itemlist_from_varlist __P((ITEMLIST *, SVFUNC *));
123
124 static STRINGLIST *gen_matches_from_itemlist __P((ITEMLIST *, const char *));
125 static STRINGLIST *gen_action_completions __P((COMPSPEC *, const char *));
126 static STRINGLIST *gen_globpat_matches __P((COMPSPEC *, const char *));
127 static STRINGLIST *gen_wordlist_matches __P((COMPSPEC *, const char *));
128 static STRINGLIST *gen_shell_function_matches __P((COMPSPEC *, const char *,
129 const char *,
130 char *, int, WORD_LIST *,
131 int, int, int *));
132 static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *,
133 const char *,
134 char *, int, WORD_LIST *,
135 int, int));
136
137 static STRINGLIST *gen_progcomp_completions __P((const char *, const char *,
138 const char *,
139 int, int, int *, int *,
140 COMPSPEC **));
141
142 static char *pcomp_filename_completion_function __P((const char *, int));
143
144 #if defined (ARRAY_VARS)
145 static SHELL_VAR *bind_comp_words __P((WORD_LIST *));
146 #endif
147 static void bind_compfunc_variables __P((char *, int, WORD_LIST *, int, int));
148 static void unbind_compfunc_variables __P((int));
149 static WORD_LIST *build_arg_list __P((char *, const char *, const char *, WORD_LIST *, int));
150 static WORD_LIST *command_line_to_word_list __P((char *, int, int, int *, int *));
151
152 #ifdef DEBUG
153 static int progcomp_debug = 0;
154 #endif
155
156 int prog_completion_enabled = 1;
157
158 /* These are used to manage the arrays of strings for possible completions. */
159 ITEMLIST it_aliases = { 0, it_init_aliases, (STRINGLIST *)0 };
160 ITEMLIST it_arrayvars = { LIST_DYNAMIC, it_init_arrayvars, (STRINGLIST *)0 };
161 ITEMLIST it_bindings = { 0, it_init_bindings, (STRINGLIST *)0 };
162 ITEMLIST it_builtins = { 0, it_init_builtins, (STRINGLIST *)0 };
163 ITEMLIST it_commands = { LIST_DYNAMIC }; /* unused */
164 ITEMLIST it_directories = { LIST_DYNAMIC }; /* unused */
165 ITEMLIST it_disabled = { 0, it_init_disabled, (STRINGLIST *)0 };
166 ITEMLIST it_enabled = { 0, it_init_enabled, (STRINGLIST *)0 };
167 ITEMLIST it_exports = { LIST_DYNAMIC, it_init_exported, (STRINGLIST *)0 };
168 ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */
169 ITEMLIST it_functions = { 0, it_init_functions, (STRINGLIST *)0 };
170 ITEMLIST it_helptopics = { 0, it_init_helptopics, (STRINGLIST *)0 };
171 ITEMLIST it_hostnames = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 };
172 ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */
173 ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 };
174 ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 };
175 ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 };
176 ITEMLIST it_services = { LIST_DYNAMIC }; /* unused */
177 ITEMLIST it_setopts = { 0, it_init_setopts, (STRINGLIST *)0 };
178 ITEMLIST it_shopts = { 0, it_init_shopts, (STRINGLIST *)0 };
179 ITEMLIST it_signals = { 0, it_init_signals, (STRINGLIST *)0 };
180 ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
181 ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
182 ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
183
184 COMPSPEC *pcomp_curcs;
185 const char *pcomp_curcmd;
186 const char *pcomp_curtxt;
187
188 #ifdef DEBUG
189 /* Debugging code */
190 static void
191 #if defined (PREFER_STDARG)
192 debug_printf (const char *format, ...)
193 #else
194 debug_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
204 SH_VA_START (args, format);
205
206 fprintf (stdout, "DEBUG: ");
207 vfprintf (stdout, format, args);
208 fprintf (stdout, "\n");
209
210 rl_on_new_line ();
211
212 va_end (args);
213 }
214 #endif
215
216 /* Functions to manage the item lists */
217
218 void
219 set_itemlist_dirty (it)
220 ITEMLIST *it;
221 {
222 it->flags |= LIST_DIRTY;
223 }
224
225 void
226 initialize_itemlist (itp)
227 ITEMLIST *itp;
228 {
229 (*itp->list_getter) (itp);
230 itp->flags |= LIST_INITIALIZED;
231 itp->flags &= ~LIST_DIRTY;
232 }
233
234 void
235 clean_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)
244 strvec_flush (sl->list);
245 if ((itp->flags & LIST_DONTFREE) == 0)
246 free (sl->list);
247 free (sl);
248 }
249 itp->slist = (STRINGLIST *)NULL;
250 itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY);
251 }
252
253
254 static int
255 shouldexp_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(). */
273 static char *
274 preproc_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*. */
289 STRINGLIST *
290 filter_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
306 ret = strlist_create (sl->list_size);
307 for (i = 0; i < sl->list_len; i++)
308 {
309 m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);
310 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
323 /* 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
325 strings in the list, unless it's the only match). */
326 STRINGLIST *
327 completions_to_stringlist (matches)
328 char **matches;
329 {
330 STRINGLIST *sl;
331 int mlen, i, n;
332
333 mlen = (matches == 0) ? 0 : strvec_len (matches);
334 sl = strlist_create (mlen + 1);
335
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
357 static int
358 it_init_aliases (itp)
359 ITEMLIST *itp;
360 {
361 #ifdef ALIAS
362 alias_t **alias_list;
363 register int i, n;
364 STRINGLIST *sl;
365
366 alias_list = all_aliases ();
367 if (alias_list == 0)
368 {
369 itp->slist = (STRINGLIST *)NULL;
370 return 0;
371 }
372 for (n = 0; alias_list[n]; n++)
373 ;
374 sl = strlist_create (n+1);
375 for (i = 0; i < n; i++)
376 sl->list[i] = STRDUP (alias_list[i]->name);
377 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
383 free (alias_list);
384 return 1;
385 }
386
387 static void
388 init_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) ();
397 if (vlist == 0)
398 {
399 itp->slist = (STRINGLIST *)NULL;
400 return;
401 }
402 for (n = 0; vlist[n]; n++)
403 ;
404 sl = strlist_create (n+1);
405 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
411 static int
412 it_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
423 static int
424 it_init_bindings (itp)
425 ITEMLIST *itp;
426 {
427 char **blist;
428 STRINGLIST *sl;
429
430 /* rl_funmap_names allocates blist, but not its members */
431 blist = (char **)rl_funmap_names (); /* XXX fix const later */
432 sl = strlist_create (0);
433 sl->list = blist;
434 sl->list_size = 0;
435 sl->list_len = strvec_len (sl->list);
436 itp->flags |= LIST_DONTFREEMEMBERS;
437 itp->slist = sl;
438
439 return 0;
440 }
441
442 static int
443 it_init_builtins (itp)
444 ITEMLIST *itp;
445 {
446 STRINGLIST *sl;
447 register int i, n;
448
449 sl = strlist_create (num_shell_builtins);
450 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
459 static int
460 it_init_enabled (itp)
461 ITEMLIST *itp;
462 {
463 STRINGLIST *sl;
464 register int i, n;
465
466 sl = strlist_create (num_shell_builtins);
467 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
478 static int
479 it_init_disabled (itp)
480 ITEMLIST *itp;
481 {
482 STRINGLIST *sl;
483 register int i, n;
484
485 sl = strlist_create (num_shell_builtins);
486 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
497 static int
498 it_init_exported (itp)
499 ITEMLIST *itp;
500 {
501 init_itemlist_from_varlist (itp, all_exported_variables);
502 return 0;
503 }
504
505 static int
506 it_init_functions (itp)
507 ITEMLIST *itp;
508 {
509 init_itemlist_from_varlist (itp, all_visible_functions);
510 return 0;
511 }
512
513 /* Like it_init_builtins, but includes everything the help builtin looks at,
514 not just builtins with an active implementing function. */
515 static int
516 it_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
531 static int
532 it_init_hostnames (itp)
533 ITEMLIST *itp;
534 {
535 STRINGLIST *sl;
536
537 sl = strlist_create (0);
538 sl->list = get_hostname_list ();
539 sl->list_len = sl->list ? strvec_len (sl->list) : 0;
540 sl->list_size = sl->list_len;
541 itp->slist = sl;
542 itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE;
543 return 0;
544 }
545
546 static int
547 it_init_joblist (itp, jstate)
548 ITEMLIST *itp;
549 int jstate;
550 {
551 #if defined (JOB_CONTROL)
552 STRINGLIST *sl;
553 register int i;
554 register PROCESS *p;
555 char *s, *t;
556 JOB *j;
557 JOB_STATE ws; /* wanted state */
558
559 ws = JNONE;
560 if (jstate == 0)
561 ws = JRUNNING;
562 else if (jstate == 1)
563 ws = JSTOPPED;
564
565 sl = strlist_create (js.j_jobslots);
566 for (i = js.j_jobslots - 1; i >= 0; i--)
567 {
568 j = get_job_by_jid (i);
569 if (j == 0)
570 continue;
571 p = j->pipe;
572 if (jstate == -1 || JOBSTATE(i) == ws)
573 {
574 s = savestring (p->command);
575 t = strpbrk (s, " \t\n");
576 if (t)
577 *t = '\0';
578 sl->list[sl->list_len++] = s;
579 }
580 }
581 itp->slist = sl;
582 #else
583 itp->slist = (STRINGLIST *)NULL;
584 #endif
585 return 0;
586 }
587
588 static int
589 it_init_jobs (itp)
590 ITEMLIST *itp;
591 {
592 return (it_init_joblist (itp, -1));
593 }
594
595 static int
596 it_init_running (itp)
597 ITEMLIST *itp;
598 {
599 return (it_init_joblist (itp, 0));
600 }
601
602 static int
603 it_init_stopped (itp)
604 ITEMLIST *itp;
605 {
606 return (it_init_joblist (itp, 1));
607 }
608
609 static int
610 it_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 ;
618 sl = strlist_create (n);
619 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
627 static int
628 it_init_signals (itp)
629 ITEMLIST *itp;
630 {
631 STRINGLIST *sl;
632
633 sl = strlist_create (0);
634 sl->list = signal_names;
635 sl->list_len = strvec_len (sl->list);
636 itp->flags |= LIST_DONTFREE;
637 itp->slist = sl;
638 return 0;
639 }
640
641 static int
642 it_init_variables (itp)
643 ITEMLIST *itp;
644 {
645 init_itemlist_from_varlist (itp, all_visible_variables);
646 return 0;
647 }
648
649 static int
650 it_init_setopts (itp)
651 ITEMLIST *itp;
652 {
653 STRINGLIST *sl;
654
655 sl = strlist_create (0);
656 sl->list = get_minus_o_opts ();
657 sl->list_len = strvec_len (sl->list);
658 itp->slist = sl;
659 itp->flags |= LIST_DONTFREEMEMBERS;
660 return 0;
661 }
662
663 static int
664 it_init_shopts (itp)
665 ITEMLIST *itp;
666 {
667 STRINGLIST *sl;
668
669 sl = strlist_create (0);
670 sl->list = get_shopt_options ();
671 sl->list_len = strvec_len (sl->list);
672 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
680 new one before trying the match. TEXT is dequoted before attempting a
681 match. */
682 static STRINGLIST *
683 gen_matches_from_itemlist (itp, text)
684 ITEMLIST *itp;
685 const char *text;
686 {
687 STRINGLIST *ret, *sl;
688 int tlen, i, n;
689 char *ntxt;
690
691 if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
692 (itp->flags & LIST_INITIALIZED) == 0)
693 {
694 if (itp->flags & (LIST_DIRTY|LIST_DYNAMIC))
695 clean_itemlist (itp);
696 if ((itp->flags & LIST_INITIALIZED) == 0)
697 initialize_itemlist (itp);
698 }
699 if (itp->slist == 0)
700 return ((STRINGLIST *)NULL);
701 ret = strlist_create (itp->slist->list_len+1);
702 sl = itp->slist;
703
704 ntxt = bash_dequote_text (text);
705 tlen = STRLEN (ntxt);
706
707 for (i = n = 0; i < sl->list_len; i++)
708 {
709 if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
710 ret->list[n++] = STRDUP (sl->list[i]);
711 }
712 ret->list[ret->list_len = n] = (char *)NULL;
713
714 FREE (ntxt);
715 return ret;
716 }
717
718 /* A wrapper for rl_filename_completion_function that dequotes the filename
719 before attempting completions. */
720 static char *
721 pcomp_filename_completion_function (text, state)
722 const char *text;
723 int state;
724 {
725 static char *dfn; /* dequoted filename */
726 int qc;
727 int iscompgen, iscompleting;
728
729 if (state == 0)
730 {
731 FREE (dfn);
732 /* remove backslashes quoting special characters in filenames. */
733 /* 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)
750 {
751 /* 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. */
755 dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
756 }
757 /* 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);
783 else
784 dfn = savestring (text);
785 }
786
787 return (rl_filename_completion_function (dfn, state));
788 }
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); \
795 if (tlist) \
796 { \
797 glist = strlist_append (glist, tlist); \
798 strlist_dispose (tlist); \
799 } \
800 } \
801 } while (0)
802
803 #define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
804 do { \
805 if (bmap & flag) \
806 { \
807 cmatches = rl_completion_matches (text, func); \
808 tlist = completions_to_stringlist (cmatches); \
809 glist = strlist_append (glist, tlist); \
810 strvec_dispose (cmatches); \
811 strlist_dispose (tlist); \
812 } \
813 } while (0)
814
815 /* Functions to generate lists of matches from the actions member of CS. */
816
817 static STRINGLIST *
818 gen_action_completions (cs, text)
819 COMPSPEC *cs;
820 const char *text;
821 {
822 STRINGLIST *ret, *tmatches;
823 char **cmatches; /* from rl_completion_matches ... */
824 unsigned long flags;
825 int t;
826
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);
838 GEN_COMPS (flags, CA_HELPTOPIC, &it_helptopics, text, ret, tmatches);
839 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);
851 GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
852 GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
853 GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
854
855 /* And lastly, the special case for directories */
856 if (flags & CA_DIRECTORY)
857 {
858 t = rl_filename_completion_desired;
859 rl_completion_mark_symlink_dirs = 1; /* override user preference */
860 cmatches = bash_directory_completion_matches (text);
861 /* 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;
867 tmatches = completions_to_stringlist (cmatches);
868 ret = strlist_append (ret, tmatches);
869 strvec_dispose (cmatches);
870 strlist_dispose (tmatches);
871 }
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. */
881 static STRINGLIST *
882 gen_globpat_matches (cs, text)
883 COMPSPEC *cs;
884 const char *text;
885 {
886 STRINGLIST *sl;
887
888 sl = strlist_create (0);
889 sl->list = glob_filename (cs->globpat, 0);
890 if (GLOB_FAILED (sl->list))
891 sl->list = (char **)NULL;
892 if (sl->list)
893 sl->list_len = sl->list_size = strvec_len (sl->list);
894 return sl;
895 }
896
897 /* Perform the shell word expansions on CS->words and return the results.
898 Again, this ignores TEXT. */
899 static STRINGLIST *
900 gen_wordlist_matches (cs, text)
901 COMPSPEC *cs;
902 const char *text;
903 {
904 WORD_LIST *l, *l2;
905 STRINGLIST *sl;
906 int nw, tlen;
907 char *ntxt; /* dequoted TEXT to use in comparisons */
908
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
915 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 */
919 l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, 0, (int *)NULL, (int *)NULL);
920 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);
927 sl = strlist_create (nw + 1);
928
929 ntxt = bash_dequote_text (text);
930 tlen = STRLEN (ntxt);
931
932 for (nw = 0, l = l2; l; l = l->next)
933 {
934 if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
935 sl->list[nw++] = STRDUP (l->word->word);
936 }
937 sl->list[sl->list_len = nw] = (char *)NULL;
938
939 dispose_words (l2);
940 FREE (ntxt);
941 return sl;
942 }
943
944 #ifdef ARRAY_VARS
945
946 static SHELL_VAR *
947 bind_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);
959 v = assign_array_var_from_word_list (v, lwords, 0);
960
961 VUNSETATTR (v, att_invisible);
962 return v;
963 }
964 #endif /* ARRAY_VARS */
965
966 static void
967 bind_compfunc_variables (line, ind, lwords, cw, exported)
968 char *line;
969 int ind;
970 WORD_LIST *lwords;
971 int cw, exported;
972 {
973 char ibuf[INT_STRLEN_BOUND(int) + 1];
974 char *value;
975 SHELL_VAR *v;
976 size_t llen;
977 int c;
978
979 /* Set the variables that the function expects while it executes. Maybe
980 these should be in the function environment (temporary_env). */
981 v = bind_variable ("COMP_LINE", line, 0);
982 if (v && exported)
983 VSETATTR(v, att_exported);
984
985 /* 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));
991 v = bind_int_variable ("COMP_POINT", value);
992 if (v && exported)
993 VSETATTR(v, att_exported);
994
995 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
1005 /* 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);
1011 value = inttostr (cw, ibuf, sizeof(ibuf));
1012 bind_int_variable ("COMP_CWORD", value);
1013 #endif
1014 }
1015 else
1016 array_needs_making = 1;
1017 }
1018
1019 static void
1020 unbind_compfunc_variables (exported)
1021 int exported;
1022 {
1023 unbind_variable ("COMP_LINE");
1024 unbind_variable ("COMP_POINT");
1025 unbind_variable ("COMP_TYPE");
1026 unbind_variable ("COMP_KEY");
1027 #ifdef ARRAY_VARS
1028 unbind_variable ("COMP_WORDS");
1029 unbind_variable ("COMP_CWORD");
1030 #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
1040 $2 == word to be completed (possibly null)
1041 $3 == previous word
1042
1043 Functions can access all of the words in the current command line
1044 with the COMP_WORDS array. External commands cannot; they have to
1045 make do with the COMP_LINE and COMP_POINT variables. */
1046
1047 static WORD_LIST *
1048 build_arg_list (cmd, cname, text, lwords, ind)
1049 char *cmd;
1050 const char *cname;
1051 const char *text;
1052 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);
1061 ret = make_word_list (w, (WORD_LIST *)NULL); /* $0 */
1062
1063 w = make_word (cname); /* $1 */
1064 cl = ret->next = make_word_list (w, (WORD_LIST *)NULL);
1065
1066 w = make_word (text);
1067 cl->next = make_word_list (w, (WORD_LIST *)NULL); /* $2 */
1068 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
1091 static STRINGLIST *
1092 gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp)
1093 COMPSPEC *cs;
1094 const char *cmd;
1095 const char *text;
1096 char *line;
1097 int ind;
1098 WORD_LIST *lwords;
1099 int nw, cw;
1100 int *foundp;
1101 {
1102 char *funcname;
1103 STRINGLIST *sl;
1104 SHELL_VAR *f, *v;
1105 WORD_LIST *cmdlist;
1106 int fval, found;
1107 sh_parser_state_t ps;
1108 sh_parser_state_t * restrict pps;
1109 #if defined (ARRAY_VARS)
1110 ARRAY *a;
1111 #endif
1112
1113 found = 0;
1114 if (foundp)
1115 *foundp = found;
1116
1117 funcname = cs->funcname;
1118 f = find_function (funcname);
1119 if (f == 0)
1120 {
1121 internal_error (_("completion: function `%s' not found"), funcname);
1122 rl_ding ();
1123 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
1135 cmdlist = build_arg_list (funcname, cmd, text, lwords, cw);
1136
1137 pps = &ps;
1138 save_parser_state (pps);
1139 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
1144 fval = execute_shell_function (f, cmdlist);
1145
1146 discard_unwind_frame ("gen-shell-function-matches");
1147 restore_parser_state (pps);
1148
1149 found = fval != EX_NOTFOUND;
1150 if (fval == EX_RETRYFAIL)
1151 found |= PCOMP_RETRYFAIL;
1152 if (foundp)
1153 *foundp = found;
1154
1155 /* 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
1166 VUNSETATTR (v, att_invisible);
1167
1168 a = array_cell (v);
1169 if (found == 0 || (found & PCOMP_RETRYFAIL) || a == 0 || array_empty (a))
1170 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. */
1175 sl = strlist_create (0);
1176 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? */
1181 unbind_variable ("COMPREPLY");
1182
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
1196 static STRINGLIST *
1197 gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw)
1198 COMPSPEC *cs;
1199 const char *cmd;
1200 const char *text;
1201 char *line;
1202 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;
1209 WORD_DESC *tw;
1210 STRINGLIST *sl;
1211
1212 bind_compfunc_variables (line, ind, lwords, cw, 1);
1213 cmdlist = build_arg_list (cs->command, cmd, text, lwords, cw);
1214
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. */
1223 cscmd = (char *)xmalloc (cmdsize + 1);
1224
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 {
1230 t = sh_single_quote (cl->word->word ? cl->word->word : "");
1231 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
1241 tw = command_substitute (cscmd, 0);
1242 csbuf = tw ? tw->word : (char *)NULL;
1243 if (tw)
1244 dispose_word_desc (tw);
1245
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. */
1259 sl = strlist_create (16);
1260 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)
1271 strlist_resize (sl, sl->list_size + 16);
1272 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
1282 static WORD_LIST *
1283 command_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
1290 #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);
1296 return (ret);
1297 }
1298
1299 /* Evaluate COMPSPEC *cs and return all matches for WORD. */
1300
1301 STRINGLIST *
1302 gen_compspec_completions (cs, cmd, word, start, end, foundp)
1303 COMPSPEC *cs;
1304 const char *cmd;
1305 const char *word;
1306 int start, end;
1307 int *foundp;
1308 {
1309 STRINGLIST *ret, *tmatches;
1310 char *line;
1311 int llen, nw, cw, found, foundf;
1312 WORD_LIST *lwords;
1313 WORD_DESC *lw;
1314 COMPSPEC *tcs;
1315
1316 found = 1;
1317
1318 #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
1322 ret = gen_action_completions (cs, word);
1323 #ifdef DEBUG
1324 if (ret && progcomp_debug)
1325 {
1326 debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
1327 strlist_print (ret, "\t");
1328 rl_on_new_line ();
1329 }
1330 #endif
1331
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 {
1338 #ifdef DEBUG
1339 if (progcomp_debug)
1340 {
1341 debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
1342 strlist_print (tmatches, "\t");
1343 rl_on_new_line ();
1344 }
1345 #endif
1346 ret = strlist_append (ret, tmatches);
1347 strlist_dispose (tmatches);
1348 rl_filename_completion_desired = 1;
1349 }
1350 }
1351
1352 if (cs->words)
1353 {
1354 tmatches = gen_wordlist_matches (cs, word);
1355 if (tmatches)
1356 {
1357 #ifdef DEBUG
1358 if (progcomp_debug)
1359 {
1360 debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
1361 strlist_print (tmatches, "\t");
1362 rl_on_new_line ();
1363 }
1364 #endif
1365 ret = strlist_append (ret, tmatches);
1366 strlist_dispose (tmatches);
1367 }
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
1380 #ifdef DEBUG
1381 debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
1382 line, llen, rl_point - start, &nw, &cw);
1383 #endif
1384 lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
1385 /* 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 }
1393 #ifdef DEBUG
1394 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 }
1405 #endif
1406 }
1407
1408 if (cs->funcname)
1409 {
1410 foundf = 0;
1411 tmatches = gen_shell_function_matches (cs, cmd, word, line, rl_point - start, lwords, nw, cw, &foundf);
1412 if (foundf != 0)
1413 found = foundf;
1414 if (tmatches)
1415 {
1416 #ifdef DEBUG
1417 if (progcomp_debug)
1418 {
1419 debug_printf ("gen_shell_function_matches (%p, %s, %s, %p, %d, %d) -->", cs, cmd, word, lwords, nw, cw);
1420 strlist_print (tmatches, "\t");
1421 rl_on_new_line ();
1422 }
1423 #endif
1424 ret = strlist_append (ret, tmatches);
1425 strlist_dispose (tmatches);
1426 }
1427 }
1428
1429 if (cs->command)
1430 {
1431 tmatches = gen_command_matches (cs, cmd, word, line, rl_point - start, lwords, nw, cw);
1432 if (tmatches)
1433 {
1434 #ifdef DEBUG
1435 if (progcomp_debug)
1436 {
1437 debug_printf ("gen_command_matches (%p, %s, %s, %p, %d, %d) -->", cs, cmd, word, lwords, nw, cw);
1438 strlist_print (tmatches, "\t");
1439 rl_on_new_line ();
1440 }
1441 #endif
1442 ret = strlist_append (ret, tmatches);
1443 strlist_dispose (tmatches);
1444 }
1445 }
1446
1447 if (cs->command || cs->funcname)
1448 {
1449 if (lwords)
1450 dispose_words (lwords);
1451 FREE (line);
1452 }
1453
1454 if (foundp)
1455 *foundp = found;
1456
1457 if (found == 0 || (found & PCOMP_RETRYFAIL))
1458 {
1459 strlist_dispose (ret);
1460 return NULL;
1461 }
1462
1463 if (cs->filterpat)
1464 {
1465 tmatches = filter_stringlist (ret, cs->filterpat, word);
1466 #ifdef DEBUG
1467 if (progcomp_debug)
1468 {
1469 debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
1470 strlist_print (tmatches, "\t");
1471 rl_on_new_line ();
1472 }
1473 #endif
1474 if (ret && ret != tmatches)
1475 {
1476 FREE (ret->list);
1477 free (ret);
1478 }
1479 ret = tmatches;
1480 }
1481
1482 if (cs->prefix || cs->suffix)
1483 ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
1484
1485 /* 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 {
1491 tcs = compspec_create ();
1492 tcs->actions = CA_DIRECTORY;
1493 FREE (ret);
1494 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);
1505 }
1506
1507 return (ret);
1508 }
1509
1510 void
1511 pcomp_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;
1521 /* 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;
1525 }
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. */
1529 void
1530 pcomp_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
1542 static STRINGLIST *
1543 gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
1544 const char *ocmd;
1545 const char *cmd;
1546 const char *word;
1547 int start, end;
1548 int *foundp, *retryp;
1549 COMPSPEC **lastcs;
1550 {
1551 COMPSPEC *cs, *oldcs;
1552 const char *oldcmd, *oldtxt;
1553 STRINGLIST *ret;
1554
1555 cs = progcomp_search (ocmd);
1556
1557 if (cs == 0 || cs == *lastcs)
1558 {
1559 #if 0
1560 if (foundp)
1561 *foundp = 0;
1562 #endif
1563 return (NULL);
1564 }
1565
1566 if (*lastcs)
1567 compspec_dispose (*lastcs);
1568 cs->refcount++; /* XXX */
1569 *lastcs = cs;
1570
1571 cs = compspec_copy (cs);
1572
1573 oldcs = pcomp_curcs;
1574 oldcmd = pcomp_curcmd;
1575 oldtxt = pcomp_curtxt;
1576
1577 pcomp_curcs = cs;
1578 pcomp_curcmd = cmd;
1579 pcomp_curtxt = word;
1580
1581 ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
1582
1583 pcomp_curcs = oldcs;
1584 pcomp_curcmd = oldcmd;
1585 pcomp_curtxt = oldtxt;
1586
1587 /* 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
1597 compspec_dispose (cs);
1598 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. */
1604 char **
1605 programmable_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);
1644
1645 if (ret)
1646 {
1647 rmatches = ret->list;
1648 free (ret);
1649 }
1650 else
1651 rmatches = (char **)NULL;
1652
1653 if (foundp)
1654 *foundp = found;
1655
1656 if (lastcs) /* XXX - should be while? */
1657 compspec_dispose (lastcs);
1658
1659 return (rmatches);
1660 }
1661
1662 #endif /* PROGRAMMABLE_COMPLETION */