diff options
| author | Jari Aalto <jari.aalto@cante.net> | 2002-07-17 14:10:11 +0000 |
|---|---|---|
| committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:55 +0000 |
| commit | 7117c2d221b2aed4ede8600f6a36b7c1454b4f55 (patch) | |
| tree | b792f26ecca68813c51ed5ba2e381790758ef31b /pcomplete.c | |
| parent | f73dda092b33638d2d5e9c35375f687a607b5403 (diff) | |
| download | android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.tar.gz android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.tar.bz2 android_external_bash-7117c2d221b2aed4ede8600f6a36b7c1454b4f55.zip | |
Imported from ../bash-2.05b.tar.gz.
Diffstat (limited to 'pcomplete.c')
| -rw-r--r-- | pcomplete.c | 187 |
1 files changed, 97 insertions, 90 deletions
diff --git a/pcomplete.c b/pcomplete.c index 17d37d5..1811351 100644 --- a/pcomplete.c +++ b/pcomplete.c @@ -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) { |
