Imported from ../bash-2.05b.tar.gz.

This commit is contained in:
Jari Aalto
2009-09-12 16:46:55 +00:00
parent f73dda092b
commit 7117c2d221
362 changed files with 34387 additions and 15063 deletions
+97 -90
View File
@@ -1,7 +1,7 @@
/* pcomplete.c - functions to generate lists of matches for programmable
completion. */
/* Copyright (C) 1999 Free Software Foundation, Inc.
/* Copyright (C) 1999-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -35,9 +35,7 @@
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# if defined (PREFER_VARARGS)
# include <varargs.h>
# endif
# include <varargs.h>
#endif
#include <stdio.h>
@@ -83,9 +81,11 @@ extern int array_needs_making;
extern STRING_INT_ALIST word_token_alist[];
extern char *signal_names[];
#if defined(PREFER_STDARG)
#if defined (DEBUG)
#if defined (PREFER_STDARG)
static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#endif
#endif /* DEBUG */
static int it_init_joblist __P((ITEMLIST *, int));
@@ -132,7 +132,9 @@ static void unbind_compfunc_variables __P((int));
static WORD_LIST *build_arg_list __P((char *, const char *, WORD_LIST *, int));
static WORD_LIST *command_line_to_word_list __P((char *, int, int, int *, int *));
#ifdef DEBUG
static int progcomp_debug = 0;
#endif
int prog_completion_enabled = 1;
@@ -146,34 +148,23 @@ ITEMLIST it_directories = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_disabled = { 0, it_init_disabled, (STRINGLIST *)0 };
ITEMLIST it_enabled = { 0, it_init_enabled, (STRINGLIST *)0 };
ITEMLIST it_exports = { LIST_DYNAMIC, it_init_exported, (STRINGLIST *)0 };
ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_functions = { 0, it_init_functions, (STRINGLIST *)0 };
ITEMLIST it_hostnames = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 };
ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 };
ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 };
ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 };
ITEMLIST it_services = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_setopts = { 0, it_init_setopts, (STRINGLIST *)0 };
ITEMLIST it_shopts = { 0, it_init_shopts, (STRINGLIST *)0 };
ITEMLIST it_signals = { 0, it_init_signals, (STRINGLIST *)0 };
ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
#ifdef DEBUG
/* Debugging code */
#if !defined (USE_VARARGS)
static void
debug_printf (format, arg1, arg2, arg3, arg4, arg5)
char *format;
{
if (progcomp_debug == 0)
return;
fprintf (stdout, format, arg1, arg2, arg3, arg4, arg5);
fprintf (stdout, "\n");
rl_on_new_line ();
}
#else
static void
#if defined (PREFER_STDARG)
debug_printf (const char *format, ...)
@@ -188,11 +179,7 @@ debug_printf (format, va_alist)
if (progcomp_debug == 0)
return;
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
#endif
SH_VA_START (args, format);
fprintf (stdout, "DEBUG: ");
vfprintf (stdout, format, args);
@@ -202,7 +189,7 @@ debug_printf (format, va_alist)
va_end (args);
}
#endif /* USE_VARARGS */
#endif
/* Functions to manage the item lists */
@@ -232,7 +219,7 @@ clean_itemlist (itp)
if (sl)
{
if ((itp->flags & (LIST_DONTFREEMEMBERS|LIST_DONTFREE)) == 0)
free_array_members (sl->list);
strvec_flush (sl->list);
if ((itp->flags & LIST_DONTFREE) == 0)
free (sl->list);
free (sl);
@@ -294,7 +281,7 @@ filter_stringlist (sl, filterpat, text)
not = (npat[0] == '!');
t = not ? npat + 1 : npat;
ret = alloc_stringlist (sl->list_size);
ret = strlist_create (sl->list_size);
for (i = 0; i < sl->list_len; i++)
{
m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);
@@ -321,8 +308,8 @@ completions_to_stringlist (matches)
STRINGLIST *sl;
int mlen, i, n;
mlen = (matches == 0) ? 0 : array_len (matches);
sl = alloc_stringlist (mlen + 1);
mlen = (matches == 0) ? 0 : strvec_len (matches);
sl = strlist_create (mlen + 1);
if (matches == 0 || matches[0] == 0)
return sl;
@@ -362,7 +349,7 @@ it_init_aliases (itp)
}
for (n = 0; alias_list[n]; n++)
;
sl = alloc_stringlist (n+1);
sl = strlist_create (n+1);
for (i = 0; i < n; i++)
sl->list[i] = STRDUP (alias_list[i]->name);
sl->list[n] = (char *)NULL;
@@ -386,7 +373,7 @@ init_itemlist_from_varlist (itp, svfunc)
vlist = (*svfunc) ();
for (n = 0; vlist[n]; n++)
;
sl = alloc_stringlist (n+1);
sl = strlist_create (n+1);
for (i = 0; i < n; i++)
sl->list[i] = savestring (vlist[i]->name);
sl->list[sl->list_len = n] = (char *)NULL;
@@ -414,10 +401,10 @@ it_init_bindings (itp)
/* rl_funmap_names allocates blist, but not its members */
blist = (char **)rl_funmap_names (); /* XXX fix const later */
sl = alloc_stringlist (0);
sl = strlist_create (0);
sl->list = blist;
sl->list_size = 0;
sl->list_len = array_len (sl->list);
sl->list_len = strvec_len (sl->list);
itp->flags |= LIST_DONTFREEMEMBERS;
itp->slist = sl;
@@ -431,7 +418,7 @@ it_init_builtins (itp)
STRINGLIST *sl;
register int i, n;
sl = alloc_stringlist (num_shell_builtins);
sl = strlist_create (num_shell_builtins);
for (i = n = 0; i < num_shell_builtins; i++)
if (shell_builtins[i].function)
sl->list[n++] = shell_builtins[i].name;
@@ -448,7 +435,7 @@ it_init_enabled (itp)
STRINGLIST *sl;
register int i, n;
sl = alloc_stringlist (num_shell_builtins);
sl = strlist_create (num_shell_builtins);
for (i = n = 0; i < num_shell_builtins; i++)
{
if (shell_builtins[i].function && (shell_builtins[i].flags & BUILTIN_ENABLED))
@@ -467,7 +454,7 @@ it_init_disabled (itp)
STRINGLIST *sl;
register int i, n;
sl = alloc_stringlist (num_shell_builtins);
sl = strlist_create (num_shell_builtins);
for (i = n = 0; i < num_shell_builtins; i++)
{
if (shell_builtins[i].function && ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
@@ -501,9 +488,9 @@ it_init_hostnames (itp)
{
STRINGLIST *sl;
sl = alloc_stringlist (0);
sl = strlist_create (0);
sl->list = get_hostname_list ();
sl->list_len = sl->list ? array_len (sl->list) : 0;
sl->list_len = sl->list ? strvec_len (sl->list) : 0;
sl->list_size = sl->list_len;
itp->slist = sl;
itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE;
@@ -527,7 +514,7 @@ it_init_joblist (itp, jstate)
else if (jstate == 1)
js = JSTOPPED;
sl = alloc_stringlist (job_slots);
sl = strlist_create (job_slots);
for (i = job_slots - 1; i >= 0; i--)
{
if (jobs[i] == 0)
@@ -579,7 +566,7 @@ it_init_keywords (itp)
for (n = 0; word_token_alist[n].word; n++)
;
sl = alloc_stringlist (n);
sl = strlist_create (n);
for (i = 0; i < n; i++)
sl->list[i] = word_token_alist[i].word;
sl->list[sl->list_len = i] = (char *)NULL;
@@ -594,9 +581,9 @@ it_init_signals (itp)
{
STRINGLIST *sl;
sl = alloc_stringlist (0);
sl = strlist_create (0);
sl->list = signal_names;
sl->list_len = array_len (sl->list);
sl->list_len = strvec_len (sl->list);
itp->flags |= LIST_DONTFREE;
itp->slist = sl;
return 0;
@@ -616,9 +603,9 @@ it_init_setopts (itp)
{
STRINGLIST *sl;
sl = alloc_stringlist (0);
sl = strlist_create (0);
sl->list = get_minus_o_opts ();
sl->list_len = array_len (sl->list);
sl->list_len = strvec_len (sl->list);
itp->slist = sl;
itp->flags |= LIST_DONTFREEMEMBERS;
return 0;
@@ -630,9 +617,9 @@ it_init_shopts (itp)
{
STRINGLIST *sl;
sl = alloc_stringlist (0);
sl = strlist_create (0);
sl->list = get_shopt_options ();
sl->list_len = array_len (sl->list);
sl->list_len = strvec_len (sl->list);
itp->slist = sl;
itp->flags |= LIST_DONTFREEMEMBERS;
return 0;
@@ -660,7 +647,7 @@ gen_matches_from_itemlist (itp, text)
}
if (itp->slist == 0)
return ((STRINGLIST *)NULL);
ret = alloc_stringlist (itp->slist->list_len+1);
ret = strlist_create (itp->slist->list_len+1);
sl = itp->slist;
tlen = STRLEN (text);
for (i = n = 0; i < sl->list_len; i++)
@@ -705,8 +692,8 @@ pcomp_filename_completion_function (text, state)
tlist = gen_matches_from_itemlist (it, text); \
if (tlist) \
{ \
glist = append_stringlist (glist, tlist); \
free_stringlist (tlist); \
glist = strlist_append (glist, tlist); \
strlist_dispose (tlist); \
} \
} \
} while (0)
@@ -717,9 +704,9 @@ pcomp_filename_completion_function (text, state)
{ \
cmatches = rl_completion_matches (text, func); \
tlist = completions_to_stringlist (cmatches); \
glist = append_stringlist (glist, tlist); \
free_array (cmatches); \
free_stringlist (tlist); \
glist = strlist_append (glist, tlist); \
strvec_dispose (cmatches); \
strlist_dispose (tlist); \
} \
} while (0)
@@ -759,15 +746,17 @@ gen_action_completions (cs, text)
GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches);
GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches);
GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches);
GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches);
/* And lastly, the special case for directories */
if (flags & CA_DIRECTORY)
{
rl_completion_mark_symlink_dirs = 1; /* override user preference */
cmatches = bash_directory_completion_matches (text);
tmatches = completions_to_stringlist (cmatches);
ret = append_stringlist (ret, tmatches);
free_array (cmatches);
free_stringlist (tmatches);
ret = strlist_append (ret, tmatches);
strvec_dispose (cmatches);
strlist_dispose (tmatches);
}
return ret;
@@ -785,12 +774,12 @@ gen_globpat_matches (cs, text)
{
STRINGLIST *sl;
sl = alloc_stringlist (0);
sl->list = glob_filename (cs->globpat);
sl = strlist_create (0);
sl->list = glob_filename (cs->globpat, 0);
if (GLOB_FAILED (sl->list))
sl->list = (char **)NULL;
if (sl->list)
sl->list_len = sl->list_size = array_len (sl->list);
sl->list_len = sl->list_size = strvec_len (sl->list);
return sl;
}
@@ -820,7 +809,7 @@ gen_wordlist_matches (cs, text)
dispose_words (l);
nw = list_length (l2);
sl = alloc_stringlist (nw + 1);
sl = strlist_create (nw + 1);
tlen = STRLEN (text);
for (nw = 0, l = l2; l; l = l->next)
@@ -893,11 +882,11 @@ static void
unbind_compfunc_variables (exported)
int exported;
{
makunbound ("COMP_LINE", shell_variables);
makunbound ("COMP_POINT", shell_variables);
unbind_variable ("COMP_LINE");
unbind_variable ("COMP_POINT");
#ifdef ARRAY_VARS
makunbound ("COMP_WORDS", shell_variables);
makunbound ("COMP_CWORD", shell_variables);
unbind_variable ("COMP_WORDS");
unbind_variable ("COMP_CWORD");
#endif
if (exported)
array_needs_making = 1;
@@ -1015,13 +1004,13 @@ gen_shell_function_matches (cs, text, line, ind, lwords, nw, cw)
{
/* XXX - should we filter the list of completions so only those matching
TEXT are returned? Right now, we do not. */
sl = alloc_stringlist (0);
sl = strlist_create (0);
sl->list = array_to_argv (a);
sl->list_len = sl->list_size = array_num_elements (a);
}
/* XXX - should we unbind COMPREPLY here? */
makunbound ("COMPREPLY", shell_variables);
unbind_variable ("COMPREPLY");
return (sl);
#endif
@@ -1094,7 +1083,7 @@ gen_command_matches (cs, text, line, ind, lwords, nw, cw)
/* Now break CSBUF up at newlines, with backslash allowed to escape a
newline, and put the individual words into a STRINGLIST. */
sl = alloc_stringlist (16);
sl = strlist_create (16);
for (ws = 0; csbuf[ws]; )
{
we = ws;
@@ -1106,7 +1095,7 @@ gen_command_matches (cs, text, line, ind, lwords, nw, cw)
}
t = substring (csbuf, ws, we);
if (sl->list_len >= sl->list_size - 1)
realloc_stringlist (sl, sl->list_size + 16);
strlist_resize (sl, sl->list_size + 16);
sl->list[sl->list_len++] = t;
while (csbuf[we] == '\n') we++;
ws = we;
@@ -1144,15 +1133,19 @@ gen_compspec_completions (cs, cmd, word, start, end)
int llen, nw, cw;
WORD_LIST *lwords;
debug_printf ("programmable_completions (%s, %s, %d, %d)", cmd, word, start, end);
debug_printf ("programmable_completions: %s -> %p", cmd, cs);
#ifdef DEBUG
debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs);
#endif
ret = gen_action_completions (cs, word);
#ifdef DEBUG
if (ret && progcomp_debug)
{
debug_printf ("gen_action_completions (%p, %s) -->", cs, word);
print_stringlist (ret, "\t");
strlist_print (ret, "\t");
rl_on_new_line ();
}
#endif
/* Now we start generating completions based on the other members of CS. */
if (cs->globpat)
@@ -1160,14 +1153,16 @@ gen_compspec_completions (cs, cmd, word, start, end)
tmatches = gen_globpat_matches (cs, word);
if (tmatches)
{
#ifdef DEBUG
if (progcomp_debug)
{
debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word);
print_stringlist (tmatches, "\t");
strlist_print (tmatches, "\t");
rl_on_new_line ();
}
ret = append_stringlist (ret, tmatches);
free_stringlist (tmatches);
#endif
ret = strlist_append (ret, tmatches);
strlist_dispose (tmatches);
rl_filename_completion_desired = 1;
}
}
@@ -1177,14 +1172,16 @@ gen_compspec_completions (cs, cmd, word, start, end)
tmatches = gen_wordlist_matches (cs, word);
if (tmatches)
{
#ifdef DEBUG
if (progcomp_debug)
{
debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word);
print_stringlist (tmatches, "\t");
strlist_print (tmatches, "\t");
rl_on_new_line ();
}
ret = append_stringlist (ret, tmatches);
free_stringlist (tmatches);
#endif
ret = strlist_append (ret, tmatches);
strlist_dispose (tmatches);
}
}
@@ -1198,9 +1195,12 @@ gen_compspec_completions (cs, cmd, word, start, end)
line = substring (rl_line_buffer, start, end);
llen = end - start;
#ifdef DEBUG
debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)",
line, llen, rl_point - start, &nw, &cw);
#endif
lwords = command_line_to_word_list (line, llen, rl_point - start, &nw, &cw);
#ifdef DEBUG
if (lwords == 0 && llen > 0)
debug_printf ("ERROR: command_line_to_word_list returns NULL");
else if (progcomp_debug)
@@ -1212,6 +1212,7 @@ gen_compspec_completions (cs, cmd, word, start, end)
fflush(stdout);
rl_on_new_line ();
}
#endif
}
if (cs->funcname)
@@ -1219,14 +1220,16 @@ gen_compspec_completions (cs, cmd, word, start, end)
tmatches = gen_shell_function_matches (cs, word, line, rl_point - start, lwords, nw, cw);
if (tmatches)
{
#ifdef DEBUG
if (progcomp_debug)
{
debug_printf ("gen_shell_function_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
print_stringlist (tmatches, "\t");
strlist_print (tmatches, "\t");
rl_on_new_line ();
}
ret = append_stringlist (ret, tmatches);
free_stringlist (tmatches);
#endif
ret = strlist_append (ret, tmatches);
strlist_dispose (tmatches);
}
}
@@ -1235,14 +1238,16 @@ gen_compspec_completions (cs, cmd, word, start, end)
tmatches = gen_command_matches (cs, word, line, rl_point - start, lwords, nw, cw);
if (tmatches)
{
#ifdef DEBUG
if (progcomp_debug)
{
debug_printf ("gen_command_matches (%p, %s, %p, %d, %d) -->", cs, word, lwords, nw, cw);
print_stringlist (tmatches, "\t");
strlist_print (tmatches, "\t");
rl_on_new_line ();
}
ret = append_stringlist (ret, tmatches);
free_stringlist (tmatches);
#endif
ret = strlist_append (ret, tmatches);
strlist_dispose (tmatches);
}
}
@@ -1256,12 +1261,14 @@ gen_compspec_completions (cs, cmd, word, start, end)
if (cs->filterpat)
{
tmatches = filter_stringlist (ret, cs->filterpat, word);
#ifdef DEBUG
if (progcomp_debug)
{
debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word);
print_stringlist (tmatches, "\t");
strlist_print (tmatches, "\t");
rl_on_new_line ();
}
#endif
if (ret && ret != tmatches)
{
FREE (ret->list);
@@ -1271,7 +1278,7 @@ gen_compspec_completions (cs, cmd, word, start, end)
}
if (cs->prefix || cs->suffix)
ret = prefix_suffix_stringlist (ret, cs->prefix, cs->suffix);
ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix);
/* If no matches have been generated and the user has specified that
directory completion should be done as a default, call
@@ -1281,10 +1288,10 @@ gen_compspec_completions (cs, cmd, word, start, end)
{
COMPSPEC *dummy;
dummy = alloc_compspec ();
dummy = compspec_create ();
dummy->actions = CA_DIRECTORY;
ret = gen_action_completions (dummy, word);
free_compspec (dummy);
compspec_dispose (dummy);
}
return (ret);
@@ -1305,12 +1312,12 @@ programmable_completions (cmd, word, start, end, foundp)
/* We look at the basename of CMD if the full command does not have
an associated COMPSPEC. */
cs = find_compspec (cmd);
cs = progcomp_search (cmd);
if (cs == 0)
{
t = strrchr (cmd, '/');
if (t)
cs = find_compspec (++t);
cs = progcomp_search (++t);
}
if (cs == 0)
{