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