1 /* pcomplete.c - functions to generate lists of matches for programmable completion. */
3 /* Copyright (C) 1999-2021 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
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/>.
23 #if defined (PROGRAMMABLE_COMPLETION)
25 #include "bashtypes.h"
26 #include "posixstat.h"
28 #if defined (HAVE_UNISTD_H)
34 #if defined (PREFER_STDARG)
40 #include "posixtime.h"
47 #include "pcomplete.h"
50 #include "execute_cmd.h"
53 #if defined (JOB_CONTROL)
64 #include "builtins/common.h"
65 #include "builtins/builtext.h"
67 #include <glob/glob.h>
68 #include <glob/strmatch.h>
70 #include <readline/rlconf.h>
71 #include <readline/readline.h>
72 #include <readline/history.h>
77 #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
79 typedef SHELL_VAR
**SVFUNC ();
82 extern char *strpbrk
PARAMS((char *, char *));
85 extern STRING_INT_ALIST word_token_alist
[];
86 extern char *signal_names
[];
89 #if defined (PREFER_STDARG)
90 static void debug_printf (const char *, ...) __attribute__((__format__ (printf
, 1, 2)));
94 static int it_init_joblist
PARAMS((ITEMLIST
*, int));
96 static int it_init_aliases
PARAMS((ITEMLIST
*));
97 static int it_init_arrayvars
PARAMS((ITEMLIST
*));
98 static int it_init_bindings
PARAMS((ITEMLIST
*));
99 static int it_init_builtins
PARAMS((ITEMLIST
*));
100 static int it_init_disabled
PARAMS((ITEMLIST
*));
101 static int it_init_enabled
PARAMS((ITEMLIST
*));
102 static int it_init_exported
PARAMS((ITEMLIST
*));
103 static int it_init_functions
PARAMS((ITEMLIST
*));
104 static int it_init_helptopics
PARAMS((ITEMLIST
*));
105 static int it_init_hostnames
PARAMS((ITEMLIST
*));
106 static int it_init_jobs
PARAMS((ITEMLIST
*));
107 static int it_init_running
PARAMS((ITEMLIST
*));
108 static int it_init_stopped
PARAMS((ITEMLIST
*));
109 static int it_init_keywords
PARAMS((ITEMLIST
*));
110 static int it_init_signals
PARAMS((ITEMLIST
*));
111 static int it_init_variables
PARAMS((ITEMLIST
*));
112 static int it_init_setopts
PARAMS((ITEMLIST
*));
113 static int it_init_shopts
PARAMS((ITEMLIST
*));
115 static int shouldexp_filterpat
PARAMS((char *));
116 static char *preproc_filterpat
PARAMS((char *, const char *));
118 static void init_itemlist_from_varlist
PARAMS((ITEMLIST
*, SVFUNC
*));
120 static STRINGLIST
*gen_matches_from_itemlist
PARAMS((ITEMLIST
*, const char *));
121 static STRINGLIST
*gen_action_completions
PARAMS((COMPSPEC
*, const char *));
122 static STRINGLIST
*gen_globpat_matches
PARAMS((COMPSPEC
*, const char *));
123 static STRINGLIST
*gen_wordlist_matches
PARAMS((COMPSPEC
*, const char *));
124 static STRINGLIST
*gen_shell_function_matches
PARAMS((COMPSPEC
*, const char *,
126 char *, int, WORD_LIST
*,
128 static STRINGLIST
*gen_command_matches
PARAMS((COMPSPEC
*, const char *,
130 char *, int, WORD_LIST
*,
133 static STRINGLIST
*gen_progcomp_completions
PARAMS((const char *, const char *,
135 int, int, int *, int *,
138 static char *pcomp_filename_completion_function
PARAMS((const char *, int));
140 #if defined (ARRAY_VARS)
141 static SHELL_VAR
*bind_comp_words
PARAMS((WORD_LIST
*));
143 static void bind_compfunc_variables
PARAMS((char *, int, WORD_LIST
*, int, int));
144 static void unbind_compfunc_variables
PARAMS((int));
145 static WORD_LIST
*build_arg_list
PARAMS((char *, const char *, const char *, WORD_LIST
*, int));
146 static WORD_LIST
*command_line_to_word_list
PARAMS((char *, int, int, int *, int *));
149 static int progcomp_debug
= 0;
152 int prog_completion_enabled
= 1;
155 int progcomp_alias
= 0; /* unavailable to user code for now */
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 };
184 COMPSPEC
*pcomp_curcs
;
185 const char *pcomp_curcmd
;
186 const char *pcomp_curtxt
;
194 #if defined (PREFER_STDARG)
195 debug_printf (const char *format
, ...)
197 debug_printf (format
, va_alist
)
204 if (progcomp_debug
== 0)
207 SH_VA_START (args
, format
);
209 fprintf (stdout
, "DEBUG: ");
210 vfprintf (stdout
, format
, args
);
211 fprintf (stdout
, "\n");
219 /* Functions to manage the item lists */
222 set_itemlist_dirty (it
)
225 it
->flags
|= LIST_DIRTY
;
229 initialize_itemlist (itp
)
232 (*itp
->list_getter
) (itp
);
233 itp
->flags
|= LIST_INITIALIZED
;
234 itp
->flags
&= ~LIST_DIRTY
;
246 if ((itp
->flags
& (LIST_DONTFREEMEMBERS
|LIST_DONTFREE
)) == 0)
247 strvec_flush (sl
->list
);
248 if ((itp
->flags
& LIST_DONTFREE
) == 0)
252 itp
->slist
= (STRINGLIST
*)NULL
;
253 itp
->flags
&= ~(LIST_DONTFREE
|LIST_DONTFREEMEMBERS
|LIST_INITIALIZED
|LIST_DIRTY
);
258 shouldexp_filterpat (s
)
263 for (p
= s
; p
&& *p
; p
++)
273 /* Replace any instance of `&' in PAT with TEXT. Backslash may be used to
274 quote a `&' and inhibit substitution. Returns a new string. This just
275 calls stringlib.c:strcreplace(). */
277 preproc_filterpat (pat
, text
)
283 ret
= strcreplace (pat
, '&', text
, 1);
287 /* Remove any match of FILTERPAT from SL. A `&' in FILTERPAT is replaced by
288 TEXT. A leading `!' in FILTERPAT negates the pattern; in this case
289 any member of SL->list that does *not* match will be removed. This returns
290 a new STRINGLIST with the matching members of SL *copied*. Any
291 non-matching members of SL->list are *freed*. */
293 filter_stringlist (sl
, filterpat
, text
)
302 if (sl
== 0 || sl
->list
== 0 || sl
->list_len
== 0)
305 npat
= shouldexp_filterpat (filterpat
) ? preproc_filterpat (filterpat
, text
) : filterpat
;
307 #if defined (EXTENDED_GLOB)
308 not = (npat
[0] == '!' && (extended_glob
== 0 || npat
[1] != '(')); /*)*/
310 not = (npat
[0] == '!');
312 t
= not ? npat
+ 1 : npat
;
314 ret
= strlist_create (sl
->list_size
);
315 for (i
= 0; i
< sl
->list_len
; i
++)
317 m
= strmatch (t
, sl
->list
[i
], FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
);
318 if ((not && m
== FNM_NOMATCH
) || (not == 0 && m
!= FNM_NOMATCH
))
321 ret
->list
[ret
->list_len
++] = sl
->list
[i
];
324 ret
->list
[ret
->list_len
] = (char *)NULL
;
325 if (npat
!= filterpat
)
331 /* Turn an array of strings returned by rl_completion_matches into a STRINGLIST.
332 This understands how rl_completion_matches sets matches[0] (the lcd of the
333 strings in the list, unless it's the only match). */
335 completions_to_stringlist (matches
)
341 mlen
= (matches
== 0) ? 0 : strvec_len (matches
);
342 sl
= strlist_create (mlen
+ 1);
344 if (matches
== 0 || matches
[0] == 0)
349 sl
->list
[0] = STRDUP (matches
[0]);
350 sl
->list
[sl
->list_len
= 1] = (char *)NULL
;
354 for (i
= 1, n
= 0; i
< mlen
; i
++, n
++)
355 sl
->list
[n
] = STRDUP (matches
[i
]);
357 sl
->list
[n
] = (char *)NULL
;
362 /* Functions to manage the various ITEMLISTs that we populate internally.
363 The caller is responsible for setting ITP->flags correctly. */
366 it_init_aliases (itp
)
370 alias_t
**alias_list
;
374 alias_list
= all_aliases ();
377 itp
->slist
= (STRINGLIST
*)NULL
;
380 for (n
= 0; alias_list
[n
]; n
++)
382 sl
= strlist_create (n
+1);
383 for (i
= 0; i
< n
; i
++)
384 sl
->list
[i
] = STRDUP (alias_list
[i
]->name
);
385 sl
->list
[n
] = (char *)NULL
;
386 sl
->list_size
= sl
->list_len
= n
;
389 itp
->slist
= (STRINGLIST
*)NULL
;
396 init_itemlist_from_varlist (itp
, svfunc
)
404 vlist
= (*svfunc
) ();
407 itp
->slist
= (STRINGLIST
*)NULL
;
410 for (n
= 0; vlist
[n
]; n
++)
412 sl
= strlist_create (n
+1);
413 for (i
= 0; i
< n
; i
++)
414 sl
->list
[i
] = savestring (vlist
[i
]->name
);
415 sl
->list
[sl
->list_len
= n
] = (char *)NULL
;
421 it_init_arrayvars (itp
)
424 #if defined (ARRAY_VARS)
425 init_itemlist_from_varlist (itp
, all_array_variables
);
433 it_init_bindings (itp
)
439 /* rl_funmap_names allocates blist, but not its members */
440 blist
= (char **)rl_funmap_names (); /* XXX fix const later */
441 sl
= strlist_create (0);
444 sl
->list_len
= strvec_len (sl
->list
);
445 itp
->flags
|= LIST_DONTFREEMEMBERS
;
452 it_init_builtins (itp
)
458 sl
= strlist_create (num_shell_builtins
);
459 for (i
= n
= 0; i
< num_shell_builtins
; i
++)
460 if (shell_builtins
[i
].function
)
461 sl
->list
[n
++] = shell_builtins
[i
].name
;
462 sl
->list
[sl
->list_len
= n
] = (char *)NULL
;
463 itp
->flags
|= LIST_DONTFREEMEMBERS
;
469 it_init_enabled (itp
)
475 sl
= strlist_create (num_shell_builtins
);
476 for (i
= n
= 0; i
< num_shell_builtins
; i
++)
478 if (shell_builtins
[i
].function
&& (shell_builtins
[i
].flags
& BUILTIN_ENABLED
))
479 sl
->list
[n
++] = shell_builtins
[i
].name
;
481 sl
->list
[sl
->list_len
= n
] = (char *)NULL
;
482 itp
->flags
|= LIST_DONTFREEMEMBERS
;
488 it_init_disabled (itp
)
494 sl
= strlist_create (num_shell_builtins
);
495 for (i
= n
= 0; i
< num_shell_builtins
; i
++)
497 if (shell_builtins
[i
].function
&& ((shell_builtins
[i
].flags
& BUILTIN_ENABLED
) == 0))
498 sl
->list
[n
++] = shell_builtins
[i
].name
;
500 sl
->list
[sl
->list_len
= n
] = (char *)NULL
;
501 itp
->flags
|= LIST_DONTFREEMEMBERS
;
507 it_init_exported (itp
)
510 init_itemlist_from_varlist (itp
, all_exported_variables
);
515 it_init_functions (itp
)
518 init_itemlist_from_varlist (itp
, all_visible_functions
);
522 /* Like it_init_builtins, but includes everything the help builtin looks at,
523 not just builtins with an active implementing function. */
525 it_init_helptopics (itp
)
531 sl
= strlist_create (num_shell_builtins
);
532 for (i
= n
= 0; i
< num_shell_builtins
; i
++)
533 sl
->list
[n
++] = shell_builtins
[i
].name
;
534 sl
->list
[sl
->list_len
= n
] = (char *)NULL
;
535 itp
->flags
|= LIST_DONTFREEMEMBERS
;
541 it_init_hostnames (itp
)
546 sl
= strlist_create (0);
547 sl
->list
= get_hostname_list ();
548 sl
->list_len
= sl
->list
? strvec_len (sl
->list
) : 0;
549 sl
->list_size
= sl
->list_len
;
551 itp
->flags
|= LIST_DONTFREEMEMBERS
|LIST_DONTFREE
;
556 it_init_joblist (itp
, jstate
)
560 #if defined (JOB_CONTROL)
566 JOB_STATE ws
; /* wanted state */
571 else if (jstate
== 1)
574 sl
= strlist_create (js
.j_jobslots
);
575 for (i
= js
.j_jobslots
- 1; i
>= 0; i
--)
577 j
= get_job_by_jid (i
);
581 if (jstate
== -1 || JOBSTATE(i
) == ws
)
583 s
= savestring (p
->command
);
584 t
= strpbrk (s
, " \t\n");
587 sl
->list
[sl
->list_len
++] = s
;
592 itp
->slist
= (STRINGLIST
*)NULL
;
601 return (it_init_joblist (itp
, -1));
605 it_init_running (itp
)
608 return (it_init_joblist (itp
, 0));
612 it_init_stopped (itp
)
615 return (it_init_joblist (itp
, 1));
619 it_init_keywords (itp
)
625 for (n
= 0; word_token_alist
[n
].word
; n
++)
627 sl
= strlist_create (n
);
628 for (i
= 0; i
< n
; i
++)
629 sl
->list
[i
] = word_token_alist
[i
].word
;
630 sl
->list
[sl
->list_len
= i
] = (char *)NULL
;
631 itp
->flags
|= LIST_DONTFREEMEMBERS
;
637 it_init_signals (itp
)
642 sl
= strlist_create (0);
643 sl
->list
= signal_names
;
644 sl
->list_len
= strvec_len (sl
->list
);
645 itp
->flags
|= LIST_DONTFREE
;
651 it_init_variables (itp
)
654 init_itemlist_from_varlist (itp
, all_visible_variables
);
659 it_init_setopts (itp
)
664 sl
= strlist_create (0);
665 sl
->list
= get_minus_o_opts ();
666 sl
->list_len
= strvec_len (sl
->list
);
668 itp
->flags
|= LIST_DONTFREEMEMBERS
;
678 sl
= strlist_create (0);
679 sl
->list
= get_shopt_options ();
680 sl
->list_len
= strvec_len (sl
->list
);
682 itp
->flags
|= LIST_DONTFREEMEMBERS
;
686 /* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
687 as the list of possibilities. If the itemlist has been marked dirty or
688 it should be regenerated every time, destroy the old STRINGLIST and make a
689 new one before trying the match. TEXT is dequoted before attempting a
692 gen_matches_from_itemlist (itp
, text
)
696 STRINGLIST
*ret
, *sl
;
700 if ((itp
->flags
& (LIST_DIRTY
|LIST_DYNAMIC
)) ||
701 (itp
->flags
& LIST_INITIALIZED
) == 0)
703 if (itp
->flags
& (LIST_DIRTY
|LIST_DYNAMIC
))
704 clean_itemlist (itp
);
705 if ((itp
->flags
& LIST_INITIALIZED
) == 0)
706 initialize_itemlist (itp
);
709 return ((STRINGLIST
*)NULL
);
710 ret
= strlist_create (itp
->slist
->list_len
+1);
713 ntxt
= bash_dequote_text (text
);
714 tlen
= STRLEN (ntxt
);
716 for (i
= n
= 0; i
< sl
->list_len
; i
++)
718 if (tlen
== 0 || STREQN (sl
->list
[i
], ntxt
, tlen
))
719 ret
->list
[n
++] = STRDUP (sl
->list
[i
]);
721 ret
->list
[ret
->list_len
= n
] = (char *)NULL
;
727 /* A wrapper for rl_filename_completion_function that dequotes the filename
728 before attempting completions. */
730 pcomp_filename_completion_function (text
, state
)
734 static char *dfn
; /* dequoted filename */
735 int iscompgen
, iscompleting
;
740 /* remove backslashes quoting special characters in filenames. */
741 /* There are roughly three paths we can follow to get here:
743 2. compgen -f "$word" from a completion function
744 3. compgen -f "$word" from the command line
745 They all need to be handled.
747 In the first two cases, readline will run the filename dequoting
748 function in rl_filename_completion_function if it found a filename
749 quoting character in the word to be completed
750 (rl_completion_found_quote). We run the dequoting function here
751 if we're running compgen, we're not completing, and the
752 rl_filename_completion_function won't dequote the filename
753 (rl_completion_found_quote == 0). */
754 iscompgen
= this_shell_builtin
== compgen_builtin
;
755 iscompleting
= RL_ISSTATE (RL_STATE_COMPLETING
);
756 if (iscompgen
&& iscompleting
== 0 && rl_completion_found_quote
== 0
757 && rl_filename_dequoting_function
)
759 /* Use rl_completion_quote_character because any single or
760 double quotes have been removed by the time TEXT makes it
761 here, and we don't want to remove backslashes inside
763 dfn
= (*rl_filename_dequoting_function
) ((char *)text
, rl_completion_quote_character
);
765 /* Intended to solve a mismatched assumption by bash-completion. If
766 the text to be completed is empty, but bash-completion turns it into
767 a quoted string ('') assuming that this code will dequote it before
768 calling readline, do the dequoting. */
769 else if (iscompgen
&& iscompleting
&&
770 pcomp_curtxt
&& *pcomp_curtxt
== 0 &&
771 text
&& (*text
== '\'' || *text
== '"') && text
[1] == text
[0] && text
[2] == 0 &&
772 rl_filename_dequoting_function
)
773 dfn
= (*rl_filename_dequoting_function
) ((char *)text
, rl_completion_quote_character
);
774 /* Another mismatched assumption by bash-completion. If compgen is being
775 run as part of bash-completion, and the argument to compgen is not
776 the same as the word originally passed to the programmable completion
777 code, dequote the argument if it has quote characters. It's an
778 attempt to detect when bash-completion is quoting its filename
779 argument before calling compgen. */
780 /* We could check whether gen_shell_function_matches is in the call
781 stack by checking whether the gen-shell-function-matches tag is in
782 the unwind-protect stack, but there's no function to do that yet.
783 We could simply check whether we're executing in a function by
784 checking variable_context, and may end up doing that. */
785 else if (iscompgen
&& iscompleting
&& rl_filename_dequoting_function
&&
786 pcomp_curtxt
&& text
&&
787 STREQ (pcomp_curtxt
, text
) == 0 &&
789 sh_contains_quotes (text
)) /* guess */
790 dfn
= (*rl_filename_dequoting_function
) ((char *)text
, rl_completion_quote_character
);
792 dfn
= savestring (text
);
795 return (rl_filename_completion_function (dfn
, state
));
798 #define GEN_COMPS(bmap, flag, it, text, glist, tlist) \
802 tlist = gen_matches_from_itemlist (it, text); \
805 glist = strlist_append (glist, tlist); \
806 strlist_dispose (tlist); \
811 #define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \
815 cmatches = rl_completion_matches (text, func); \
816 tlist = completions_to_stringlist (cmatches); \
817 glist = strlist_append (glist, tlist); \
818 strvec_dispose (cmatches); \
819 strlist_dispose (tlist); \
823 /* Functions to generate lists of matches from the actions member of CS. */
826 gen_action_completions (cs
, text
)
830 STRINGLIST
*ret
, *tmatches
;
831 char **cmatches
; /* from rl_completion_matches ... */
835 ret
= tmatches
= (STRINGLIST
*)NULL
;
838 GEN_COMPS (flags
, CA_ALIAS
, &it_aliases
, text
, ret
, tmatches
);
839 GEN_COMPS (flags
, CA_ARRAYVAR
, &it_arrayvars
, text
, ret
, tmatches
);
840 GEN_COMPS (flags
, CA_BINDING
, &it_bindings
, text
, ret
, tmatches
);
841 GEN_COMPS (flags
, CA_BUILTIN
, &it_builtins
, text
, ret
, tmatches
);
842 GEN_COMPS (flags
, CA_DISABLED
, &it_disabled
, text
, ret
, tmatches
);
843 GEN_COMPS (flags
, CA_ENABLED
, &it_enabled
, text
, ret
, tmatches
);
844 GEN_COMPS (flags
, CA_EXPORT
, &it_exports
, text
, ret
, tmatches
);
845 GEN_COMPS (flags
, CA_FUNCTION
, &it_functions
, text
, ret
, tmatches
);
846 GEN_COMPS (flags
, CA_HELPTOPIC
, &it_helptopics
, text
, ret
, tmatches
);
847 GEN_COMPS (flags
, CA_HOSTNAME
, &it_hostnames
, text
, ret
, tmatches
);
848 GEN_COMPS (flags
, CA_JOB
, &it_jobs
, text
, ret
, tmatches
);
849 GEN_COMPS (flags
, CA_KEYWORD
, &it_keywords
, text
, ret
, tmatches
);
850 GEN_COMPS (flags
, CA_RUNNING
, &it_running
, text
, ret
, tmatches
);
851 GEN_COMPS (flags
, CA_SETOPT
, &it_setopts
, text
, ret
, tmatches
);
852 GEN_COMPS (flags
, CA_SHOPT
, &it_shopts
, text
, ret
, tmatches
);
853 GEN_COMPS (flags
, CA_SIGNAL
, &it_signals
, text
, ret
, tmatches
);
854 GEN_COMPS (flags
, CA_STOPPED
, &it_stopped
, text
, ret
, tmatches
);
855 GEN_COMPS (flags
, CA_VARIABLE
, &it_variables
, text
, ret
, tmatches
);
857 GEN_XCOMPS(flags
, CA_COMMAND
, text
, command_word_completion_function
, cmatches
, ret
, tmatches
);
858 GEN_XCOMPS(flags
, CA_FILE
, text
, pcomp_filename_completion_function
, cmatches
, ret
, tmatches
);
859 GEN_XCOMPS(flags
, CA_USER
, text
, rl_username_completion_function
, cmatches
, ret
, tmatches
);
860 GEN_XCOMPS(flags
, CA_GROUP
, text
, bash_groupname_completion_function
, cmatches
, ret
, tmatches
);
861 GEN_XCOMPS(flags
, CA_SERVICE
, text
, bash_servicename_completion_function
, cmatches
, ret
, tmatches
);
863 /* And lastly, the special case for directories */
864 if (flags
& CA_DIRECTORY
)
866 t
= rl_filename_completion_desired
;
867 rl_completion_mark_symlink_dirs
= 1; /* override user preference */
868 cmatches
= bash_directory_completion_matches (text
);
869 /* If we did not want filename completion before this, and there are
870 no matches, turn off rl_filename_completion_desired so whatever
871 matches we get are not treated as filenames (it gets turned on by
872 rl_filename_completion_function unconditionally). */
873 if (t
== 0 && cmatches
== 0 && rl_filename_completion_desired
== 1)
874 rl_filename_completion_desired
= 0;
875 tmatches
= completions_to_stringlist (cmatches
);
876 ret
= strlist_append (ret
, tmatches
);
877 strvec_dispose (cmatches
);
878 strlist_dispose (tmatches
);
884 /* Generate a list of matches for CS->globpat. Unresolved: should this use
885 TEXT as a match prefix, or just go without? Currently, the code does not
886 use TEXT, just globs CS->globpat and returns the results. If we do decide
887 to use TEXT, we should call quote_string_for_globbing before the call to
888 glob_filename (in which case we could use shell_glob_filename). */
890 gen_globpat_matches (cs
, text
)
897 sl
= strlist_create (0);
898 gflags
= glob_star
? GX_GLOBSTAR
: 0;
899 sl
->list
= glob_filename (cs
->globpat
, gflags
);
900 if (GLOB_FAILED (sl
->list
))
901 sl
->list
= (char **)NULL
;
903 sl
->list_len
= sl
->list_size
= strvec_len (sl
->list
);
907 /* Perform the shell word expansions on CS->words and return the results.
908 Again, this ignores TEXT. */
910 gen_wordlist_matches (cs
, text
)
917 char *ntxt
; /* dequoted TEXT to use in comparisons */
919 if (cs
->words
== 0 || cs
->words
[0] == '\0')
920 return ((STRINGLIST
*)NULL
);
922 /* This used to be a simple expand_string(cs->words, 0), but that won't
923 do -- there's no way to split a simple list into individual words
924 that way, since the shell semantics say that word splitting is done
925 only on the results of expansion. split_at_delims also handles embedded
926 quoted strings and preserves the quotes for the expand_words_shellexp
927 function call that follows. */
928 /* XXX - this is where this function spends most of its time */
929 l
= split_at_delims (cs
->words
, strlen (cs
->words
), (char *)NULL
, -1, 0, (int *)NULL
, (int *)NULL
);
931 return ((STRINGLIST
*)NULL
);
932 /* This will jump back to the top level if the expansion fails... */
933 l2
= expand_words_shellexp (l
);
936 nw
= list_length (l2
);
937 sl
= strlist_create (nw
+ 1);
939 ntxt
= bash_dequote_text (text
);
940 tlen
= STRLEN (ntxt
);
942 for (nw
= 0, l
= l2
; l
; l
= l
->next
)
944 if (tlen
== 0 || STREQN (l
->word
->word
, ntxt
, tlen
))
945 sl
->list
[nw
++] = STRDUP (l
->word
->word
);
947 sl
->list
[sl
->list_len
= nw
] = (char *)NULL
;
957 bind_comp_words (lwords
)
962 v
= find_variable_noref ("COMP_WORDS");
964 v
= make_new_array_variable ("COMP_WORDS");
966 VUNSETATTR (v
, att_nameref
);
969 VUNSETATTR (v
, att_readonly
);
971 if (array_p (v
) == 0)
972 v
= convert_var_to_array (v
);
973 v
= assign_array_var_from_word_list (v
, lwords
, 0);
975 VUNSETATTR (v
, att_invisible
);
978 #endif /* ARRAY_VARS */
981 bind_compfunc_variables (line
, ind
, lwords
, cw
, exported
)
987 char ibuf
[INT_STRLEN_BOUND(int) + 1];
993 /* Set the variables that the function expects while it executes. Maybe
994 these should be in the function environment (temporary_env). */
995 v
= bind_variable ("COMP_LINE", line
, 0);
997 VSETATTR(v
, att_exported
);
999 /* Post bash-4.2: COMP_POINT is characters instead of bytes. */
1002 llen
= MB_STRLEN (line
);
1004 value
= inttostr (llen
, ibuf
, sizeof(ibuf
));
1005 v
= bind_int_variable ("COMP_POINT", value
, 0);
1007 VSETATTR(v
, att_exported
);
1009 value
= inttostr (rl_completion_type
, ibuf
, sizeof (ibuf
));
1010 v
= bind_int_variable ("COMP_TYPE", value
, 0);
1012 VSETATTR(v
, att_exported
);
1014 value
= inttostr (rl_completion_invoking_key
, ibuf
, sizeof (ibuf
));
1015 v
= bind_int_variable ("COMP_KEY", value
, 0);
1017 VSETATTR(v
, att_exported
);
1019 /* Since array variables can't be exported, we don't bother making the
1024 v
= bind_comp_words (lwords
);
1025 value
= inttostr (cw
, ibuf
, sizeof(ibuf
));
1026 bind_int_variable ("COMP_CWORD", value
, 0);
1030 array_needs_making
= 1;
1034 unbind_compfunc_variables (exported
)
1037 unbind_variable_noref ("COMP_LINE");
1038 unbind_variable_noref ("COMP_POINT");
1039 unbind_variable_noref ("COMP_TYPE");
1040 unbind_variable_noref ("COMP_KEY");
1042 unbind_variable_noref ("COMP_WORDS");
1043 unbind_variable_noref ("COMP_CWORD");
1046 array_needs_making
= 1;
1049 /* Build the list of words to pass to a function or external command
1050 as arguments. When the function or command is invoked,
1052 $0 == function or command being invoked
1054 $2 == word to be completed (possibly null)
1057 Functions can access all of the words in the current command line
1058 with the COMP_WORDS array. External commands cannot; they have to
1059 make do with the COMP_LINE and COMP_POINT variables. */
1062 build_arg_list (cmd
, cname
, text
, lwords
, ind
)
1069 WORD_LIST
*ret
, *cl
, *l
;
1073 ret
= (WORD_LIST
*)NULL
;
1074 w
= make_word (cmd
);
1075 ret
= make_word_list (w
, (WORD_LIST
*)NULL
); /* $0 */
1077 w
= make_word (cname
); /* $1 */
1078 cl
= ret
->next
= make_word_list (w
, (WORD_LIST
*)NULL
);
1080 w
= make_word (text
);
1081 cl
->next
= make_word_list (w
, (WORD_LIST
*)NULL
); /* $2 */
1084 /* Search lwords for current word */
1085 for (l
= lwords
, i
= 1; l
&& i
< ind
-1; l
= l
->next
, i
++)
1087 w
= (l
&& l
->word
) ? copy_word (l
->word
) : make_word ("");
1088 cl
->next
= make_word_list (w
, (WORD_LIST
*)NULL
);
1093 /* Build a command string with
1094 $0 == cs->funcname (function to execute for completion list)
1095 $1 == command name (command being completed)
1096 $2 = word to be completed (possibly null)
1098 and run in the current shell. The function should put its completion
1099 list into the array variable COMPREPLY. We build a STRINGLIST
1100 from the results and return it.
1102 Since the shell function should return its list of matches in an array
1103 variable, this does nothing if arrays are not compiled into the shell. */
1106 gen_shell_function_matches (cs
, cmd
, text
, line
, ind
, lwords
, nw
, cw
, foundp
)
1121 sh_parser_state_t ps
;
1122 sh_parser_state_t
* restrict pps
;
1123 #if defined (ARRAY_VARS)
1131 funcname
= cs
->funcname
;
1132 f
= find_function (funcname
);
1135 internal_error (_("completion: function `%s' not found"), funcname
);
1138 return ((STRINGLIST
*)NULL
);
1141 #if !defined (ARRAY_VARS)
1142 return ((STRINGLIST
*)NULL
);
1145 /* We pass cw - 1 because command_line_to_word_list returns indices that are
1146 1-based, while bash arrays are 0-based. */
1147 bind_compfunc_variables (line
, ind
, lwords
, cw
- 1, 0);
1149 cmdlist
= build_arg_list (funcname
, cmd
, text
, lwords
, cw
);
1152 save_parser_state (pps
);
1153 begin_unwind_frame ("gen-shell-function-matches");
1154 add_unwind_protect (restore_parser_state
, (char *)pps
);
1155 add_unwind_protect (dispose_words
, (char *)cmdlist
);
1156 add_unwind_protect (unbind_compfunc_variables
, (char *)0);
1158 fval
= execute_shell_function (f
, cmdlist
);
1160 discard_unwind_frame ("gen-shell-function-matches");
1161 restore_parser_state (pps
);
1163 found
= fval
!= EX_NOTFOUND
;
1164 if (fval
== EX_RETRYFAIL
)
1165 found
|= PCOMP_RETRYFAIL
;
1169 /* Now clean up and destroy everything. */
1170 dispose_words (cmdlist
);
1171 unbind_compfunc_variables (0);
1173 /* The list of completions is returned in the array variable COMPREPLY. */
1174 v
= find_variable ("COMPREPLY");
1176 return ((STRINGLIST
*)NULL
);
1177 if (array_p (v
) == 0 && assoc_p (v
) == 0)
1178 v
= convert_var_to_array (v
);
1180 VUNSETATTR (v
, att_invisible
);
1183 if (found
== 0 || (found
& PCOMP_RETRYFAIL
) || a
== 0 || array_p (v
) == 0 || array_empty (a
))
1184 sl
= (STRINGLIST
*)NULL
;
1187 /* XXX - should we filter the list of completions so only those matching
1188 TEXT are returned? Right now, we do not. */
1189 sl
= strlist_create (0);
1190 sl
->list
= array_to_argv (a
, 0);
1191 sl
->list_len
= sl
->list_size
= array_num_elements (a
);
1194 /* XXX - should we unbind COMPREPLY here? */
1195 unbind_variable_noref ("COMPREPLY");
1201 /* Build a command string with
1202 $0 == cs->command (command to execute for completion list)
1203 $1 == command name (command being completed)
1204 $2 == word to be completed (possibly null)
1206 and run it with command substitution. Parse the results, one word
1207 per line, with backslashes allowed to escape newlines. Build a
1208 STRINGLIST from the results and return it. */
1211 gen_command_matches (cs
, cmd
, text
, line
, ind
, lwords
, nw
, cw
)
1220 char *csbuf
, *cscmd
, *t
;
1221 int cmdlen
, cmdsize
, n
, ws
, we
;
1222 WORD_LIST
*cmdlist
, *cl
;
1226 bind_compfunc_variables (line
, ind
, lwords
, cw
, 1);
1227 cmdlist
= build_arg_list (cs
->command
, cmd
, text
, lwords
, cw
);
1229 /* Estimate the size needed for the buffer. */
1230 n
= strlen (cs
->command
);
1232 for (cl
= cmdlist
->next
; cl
; cl
= cl
->next
)
1233 cmdsize
+= STRLEN (cl
->word
->word
) + 3;
1236 /* allocate the string for the command and fill it in. */
1237 cscmd
= (char *)xmalloc (cmdsize
+ 1);
1239 strcpy (cscmd
, cs
->command
); /* $0 */
1241 cscmd
[cmdlen
++] = ' ';
1242 for (cl
= cmdlist
->next
; cl
; cl
= cl
->next
) /* $1, $2, $3, ... */
1244 t
= sh_single_quote (cl
->word
->word
? cl
->word
->word
: "");
1246 RESIZE_MALLOCED_BUFFER (cscmd
, cmdlen
, n
+ 2, cmdsize
, 64);
1247 strcpy (cscmd
+ cmdlen
, t
);
1250 cscmd
[cmdlen
++] = ' ';
1253 cscmd
[cmdlen
] = '\0';
1255 tw
= command_substitute (cscmd
, 0, 0);
1256 csbuf
= tw
? tw
->word
: (char *)NULL
;
1258 dispose_word_desc (tw
);
1260 /* Now clean up and destroy everything. */
1261 dispose_words (cmdlist
);
1263 unbind_compfunc_variables (1);
1265 if (csbuf
== 0 || *csbuf
== '\0')
1268 return ((STRINGLIST
*)NULL
);
1271 /* Now break CSBUF up at newlines, with backslash allowed to escape a
1272 newline, and put the individual words into a STRINGLIST. */
1273 sl
= strlist_create (16);
1274 for (ws
= 0; csbuf
[ws
]; )
1277 while (csbuf
[we
] && csbuf
[we
] != '\n')
1279 if (csbuf
[we
] == '\\' && csbuf
[we
+1] == '\n')
1283 t
= substring (csbuf
, ws
, we
);
1284 if (sl
->list_len
>= sl
->list_size
- 1)
1285 strlist_resize (sl
, sl
->list_size
+ 16);
1286 sl
->list
[sl
->list_len
++] = t
;
1287 while (csbuf
[we
] == '\n') we
++;
1290 sl
->list
[sl
->list_len
] = (char *)NULL
;
1297 command_line_to_word_list (line
, llen
, sentinel
, nwp
, cwp
)
1299 int llen
, sentinel
, *nwp
, *cwp
;
1305 delims
= "()<>;&| \t\n"; /* shell metacharacters break words */
1307 delims
= rl_completer_word_break_characters
;
1309 ret
= split_at_delims (line
, llen
, delims
, sentinel
, SD_NOQUOTEDELIM
|SD_COMPLETE
, nwp
, cwp
);
1313 /* Evaluate COMPSPEC *cs and return all matches for WORD. */
1316 gen_compspec_completions (cs
, cmd
, word
, start
, end
, foundp
)
1323 STRINGLIST
*ret
, *tmatches
;
1325 int llen
, nw
, cw
, found
, foundf
;
1333 debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd
, word
, start
, end
);
1334 debug_printf ("gen_compspec_completions: %s -> %p", cmd
, cs
);
1336 ret
= gen_action_completions (cs
, word
);
1338 if (ret
&& progcomp_debug
)
1340 debug_printf ("gen_action_completions (%p, %s) -->", cs
, word
);
1341 strlist_print (ret
, "\t");
1346 /* Now we start generating completions based on the other members of CS. */
1349 tmatches
= gen_globpat_matches (cs
, word
);
1355 debug_printf ("gen_globpat_matches (%p, %s) -->", cs
, word
);
1356 strlist_print (tmatches
, "\t");
1360 ret
= strlist_append (ret
, tmatches
);
1361 strlist_dispose (tmatches
);
1362 rl_filename_completion_desired
= 1;
1368 tmatches
= gen_wordlist_matches (cs
, word
);
1374 debug_printf ("gen_wordlist_matches (%p, %s) -->", cs
, word
);
1375 strlist_print (tmatches
, "\t");
1379 ret
= strlist_append (ret
, tmatches
);
1380 strlist_dispose (tmatches
);
1384 lwords
= (WORD_LIST
*)NULL
;
1385 line
= (char *)NULL
;
1386 if (cs
->command
|| cs
->funcname
)
1388 /* If we have a command or function to execute, we need to first break
1389 the command line into individual words, find the number of words,
1390 and find the word in the list containing the word to be completed. */
1391 line
= substring (pcomp_line
, start
, end
);
1395 debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
1396 line
, llen
, pcomp_ind
- start
, &nw
, &cw
);
1398 lwords
= command_line_to_word_list (line
, llen
, pcomp_ind
- start
, &nw
, &cw
);
1399 /* If we skipped a NULL word at the beginning of the line, add it back */
1400 if (lwords
&& lwords
->word
&& cmd
[0] == 0 && lwords
->word
->word
[0] != 0)
1402 lw
= make_bare_word (cmd
);
1403 lwords
= make_word_list (lw
, lwords
);
1408 if (lwords
== 0 && llen
> 0)
1409 debug_printf ("ERROR: command_line_to_word_list returns NULL");
1410 else if (progcomp_debug
)
1412 debug_printf ("command_line_to_word_list -->");
1414 print_word_list (lwords
, "!");
1425 tmatches
= gen_shell_function_matches (cs
, cmd
, word
, line
, pcomp_ind
- start
, lwords
, nw
, cw
, &foundf
);
1433 debug_printf ("gen_shell_function_matches (%p, %s, %s, %p, %d, %d) -->", cs
, cmd
, word
, lwords
, nw
, cw
);
1434 strlist_print (tmatches
, "\t");
1438 ret
= strlist_append (ret
, tmatches
);
1439 strlist_dispose (tmatches
);
1445 tmatches
= gen_command_matches (cs
, cmd
, word
, line
, pcomp_ind
- start
, lwords
, nw
, cw
);
1451 debug_printf ("gen_command_matches (%p, %s, %s, %p, %d, %d) -->", cs
, cmd
, word
, lwords
, nw
, cw
);
1452 strlist_print (tmatches
, "\t");
1456 ret
= strlist_append (ret
, tmatches
);
1457 strlist_dispose (tmatches
);
1461 if (cs
->command
|| cs
->funcname
)
1464 dispose_words (lwords
);
1471 if (found
== 0 || (found
& PCOMP_RETRYFAIL
))
1473 strlist_dispose (ret
);
1479 tmatches
= filter_stringlist (ret
, cs
->filterpat
, word
);
1483 debug_printf ("filter_stringlist (%p, %s, %s) -->", ret
, cs
->filterpat
, word
);
1484 strlist_print (tmatches
, "\t");
1488 if (ret
&& ret
!= tmatches
)
1496 if (cs
->prefix
|| cs
->suffix
)
1497 ret
= strlist_prefix_suffix (ret
, cs
->prefix
, cs
->suffix
);
1499 /* If no matches have been generated and the user has specified that
1500 directory completion should be done as a default, call
1501 gen_action_completions again to generate a list of matching directory
1503 if ((ret
== 0 || ret
->list_len
== 0) && (cs
->options
& COPT_DIRNAMES
))
1505 tcs
= compspec_create ();
1506 tcs
->actions
= CA_DIRECTORY
;
1508 ret
= gen_action_completions (tcs
, word
);
1509 compspec_dispose (tcs
);
1511 else if (cs
->options
& COPT_PLUSDIRS
)
1513 tcs
= compspec_create ();
1514 tcs
->actions
= CA_DIRECTORY
;
1515 tmatches
= gen_action_completions (tcs
, word
);
1516 ret
= strlist_append (ret
, tmatches
);
1517 strlist_dispose (tmatches
);
1518 compspec_dispose (tcs
);
1525 pcomp_set_readline_variables (flags
, nval
)
1528 /* If the user specified that the compspec returns filenames, make
1529 sure that readline knows it. */
1530 if (flags
& COPT_FILENAMES
)
1531 rl_filename_completion_desired
= nval
;
1532 /* If the user doesn't want a space appended, tell readline. */
1533 if (flags
& COPT_NOSPACE
)
1534 rl_completion_suppress_append
= nval
;
1535 /* The value here is inverted, since the default is on and the `noquote'
1536 option is supposed to turn it off */
1537 if (flags
& COPT_NOQUOTE
)
1538 rl_filename_quoting_desired
= 1 - nval
;
1539 if (flags
& COPT_NOSORT
)
1540 rl_sort_completion_matches
= 1 - nval
;
1543 /* Set or unset FLAGS in the options word of the current compspec.
1544 SET_OR_UNSET is 1 for setting, 0 for unsetting. */
1546 pcomp_set_compspec_options (cs
, flags
, set_or_unset
)
1548 int flags
, set_or_unset
;
1550 if (cs
== 0 && ((cs
= pcomp_curcs
) == 0))
1553 cs
->options
|= flags
;
1555 cs
->options
&= ~flags
;
1559 gen_progcomp_completions (ocmd
, cmd
, word
, start
, end
, foundp
, retryp
, lastcs
)
1564 int *foundp
, *retryp
;
1567 COMPSPEC
*cs
, *oldcs
;
1568 const char *oldcmd
, *oldtxt
;
1571 cs
= progcomp_search (ocmd
);
1573 if (cs
== 0 || cs
== *lastcs
)
1583 compspec_dispose (*lastcs
);
1584 cs
->refcount
++; /* XXX */
1587 cs
= compspec_copy (cs
);
1589 oldcs
= pcomp_curcs
;
1590 oldcmd
= pcomp_curcmd
;
1591 oldtxt
= pcomp_curtxt
;
1595 pcomp_curtxt
= word
;
1597 ret
= gen_compspec_completions (cs
, cmd
, word
, start
, end
, foundp
);
1599 pcomp_curcs
= oldcs
;
1600 pcomp_curcmd
= oldcmd
;
1601 pcomp_curtxt
= oldtxt
;
1603 /* We need to conditionally handle setting *retryp here */
1605 *retryp
= foundp
&& (*foundp
& PCOMP_RETRYFAIL
);
1609 *foundp
&= ~PCOMP_RETRYFAIL
;
1610 *foundp
|= cs
->options
;
1613 compspec_dispose (cs
);
1617 /* The driver function for the programmable completion code. Returns a list
1618 of matches for WORD, which is an argument to command CMD. START and END
1619 bound the command currently being completed in pcomp_line (usually
1622 programmable_completions (cmd
, word
, start
, end
, foundp
)
1625 int start
, end
, *foundp
;
1629 char **rmatches
, *t
;
1630 int found
, retry
, count
;
1640 pcomp_line
= rl_line_buffer
;
1641 pcomp_ind
= rl_point
;
1650 /* We look at the basename of CMD if the full command does not have
1651 an associated COMPSPEC. */
1652 ret
= gen_progcomp_completions (ocmd
, ocmd
, word
, start
, oend
, &found
, &retry
, &lastcs
);
1655 t
= strrchr (ocmd
, '/');
1657 ret
= gen_progcomp_completions (t
, ocmd
, word
, start
, oend
, &found
, &retry
, &lastcs
);
1661 ret
= gen_progcomp_completions (DEFAULTCMD
, ocmd
, word
, start
, oend
, &found
, &retry
, &lastcs
);
1664 /* Look up any alias for CMD, try to gen completions for it */
1665 /* Look up the alias, find the value, build a new line replacing CMD
1666 with that value, offsetting PCOMP_IND and END appropriately, reset
1667 PCOMP_LINE to the new line and OCMD with the new command name, then
1668 call gen_progcomp_completions again. We could use alias_expand for
1669 this, but it does more (and less) than we need right now. */
1670 if (found
== 0 && retry
== 0 && progcomp_alias
&& (al
= find_alias (ocmd
)))
1672 char *ncmd
, *nline
, *ntxt
;
1674 size_t nlen
, olen
, llen
;
1676 /* We found an alias for OCMD. Take the value and build a new line */
1678 nlen
= strlen (ntxt
);
1681 olen
= strlen (ocmd
);
1682 lendiff
= nlen
- olen
; /* can be negative */
1683 llen
= strlen (pcomp_line
);
1685 nline
= (char *)xmalloc (llen
+ lendiff
+ 1);
1687 strncpy (nline
, pcomp_line
, start
);
1688 strncpy (nline
+ start
, ntxt
, nlen
);
1689 strcpy (nline
+ start
+ nlen
, pcomp_line
+ start
+ olen
);
1691 /* Find the first word of the alias value and use that as OCMD. We
1692 don't check the alias value to see whether it begins with a valid
1693 command name, so this can be fooled. */
1694 ind
= skip_to_delim (ntxt
, 0, "()<>;&| \t\n", SD_NOJMP
|SD_COMPLETE
);
1696 ncmd
= substring (ntxt
, 0, ind
);
1700 break; /* will free pcomp_line and ocmd later */
1703 /* Adjust PCOMP_IND and OEND appropriately */
1704 pcomp_ind
+= lendiff
;
1707 /* Set up values with new line. WORD stays the same. */
1710 if (pcomp_line
!= rl_line_buffer
)
1716 /* And go back and start over. */
1725 internal_warning (_("programmable_completion: %s: possible retry loop"), cmd
);
1731 if (pcomp_line
!= rl_line_buffer
)
1738 rmatches
= ret
->list
;
1742 rmatches
= (char **)NULL
;
1747 if (lastcs
) /* XXX - should be while? */
1748 compspec_dispose (lastcs
);
1750 /* XXX restore pcomp_line and pcomp_ind? */
1751 pcomp_line
= rl_line_buffer
;
1752 pcomp_ind
= rl_point
;
1757 #endif /* PROGRAMMABLE_COMPLETION */