mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-14 07:30:49 +02:00
Bash-5.3-alpha release
This commit is contained in:
+149
-220
@@ -1,6 +1,6 @@
|
||||
/* pcomplete.c - functions to generate lists of matches for programmable completion. */
|
||||
|
||||
/* Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -31,11 +31,7 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "posixtime.h"
|
||||
|
||||
@@ -76,74 +72,74 @@
|
||||
#endif
|
||||
#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
|
||||
|
||||
typedef SHELL_VAR **SVFUNC ();
|
||||
typedef SHELL_VAR **SVFUNC (void);
|
||||
|
||||
#ifndef HAVE_STRPBRK
|
||||
extern char *strpbrk PARAMS((char *, char *));
|
||||
extern char *strpbrk (char *, char *);
|
||||
#endif
|
||||
|
||||
extern STRING_INT_ALIST word_token_alist[];
|
||||
extern char *signal_names[];
|
||||
|
||||
#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 PARAMS((ITEMLIST *, int));
|
||||
static int it_init_joblist (ITEMLIST *, int);
|
||||
|
||||
static int it_init_aliases PARAMS((ITEMLIST *));
|
||||
static int it_init_arrayvars PARAMS((ITEMLIST *));
|
||||
static int it_init_bindings PARAMS((ITEMLIST *));
|
||||
static int it_init_builtins PARAMS((ITEMLIST *));
|
||||
static int it_init_disabled PARAMS((ITEMLIST *));
|
||||
static int it_init_enabled PARAMS((ITEMLIST *));
|
||||
static int it_init_exported PARAMS((ITEMLIST *));
|
||||
static int it_init_functions PARAMS((ITEMLIST *));
|
||||
static int it_init_helptopics PARAMS((ITEMLIST *));
|
||||
static int it_init_hostnames PARAMS((ITEMLIST *));
|
||||
static int it_init_jobs PARAMS((ITEMLIST *));
|
||||
static int it_init_running PARAMS((ITEMLIST *));
|
||||
static int it_init_stopped PARAMS((ITEMLIST *));
|
||||
static int it_init_keywords PARAMS((ITEMLIST *));
|
||||
static int it_init_signals PARAMS((ITEMLIST *));
|
||||
static int it_init_variables PARAMS((ITEMLIST *));
|
||||
static int it_init_setopts PARAMS((ITEMLIST *));
|
||||
static int it_init_shopts PARAMS((ITEMLIST *));
|
||||
static int it_init_aliases (ITEMLIST *);
|
||||
static int it_init_arrayvars (ITEMLIST *);
|
||||
static int it_init_bindings (ITEMLIST *);
|
||||
static int it_init_builtins (ITEMLIST *);
|
||||
static int it_init_disabled (ITEMLIST *);
|
||||
static int it_init_enabled (ITEMLIST *);
|
||||
static int it_init_exported (ITEMLIST *);
|
||||
static int it_init_functions (ITEMLIST *);
|
||||
static int it_init_helptopics (ITEMLIST *);
|
||||
static int it_init_hostnames (ITEMLIST *);
|
||||
static int it_init_jobs (ITEMLIST *);
|
||||
static int it_init_running (ITEMLIST *);
|
||||
static int it_init_stopped (ITEMLIST *);
|
||||
static int it_init_keywords (ITEMLIST *);
|
||||
static int it_init_signals (ITEMLIST *);
|
||||
static int it_init_variables (ITEMLIST *);
|
||||
static int it_init_setopts (ITEMLIST *);
|
||||
static int it_init_shopts (ITEMLIST *);
|
||||
|
||||
static int shouldexp_filterpat PARAMS((char *));
|
||||
static char *preproc_filterpat PARAMS((char *, const char *));
|
||||
static int shouldexp_filterpat (char *);
|
||||
static char *preproc_filterpat (const char *, const char *);
|
||||
|
||||
static void init_itemlist_from_varlist PARAMS((ITEMLIST *, SVFUNC *));
|
||||
static void init_itemlist_from_varlist (ITEMLIST *, SVFUNC *);
|
||||
|
||||
static STRINGLIST *gen_matches_from_itemlist PARAMS((ITEMLIST *, const char *));
|
||||
static STRINGLIST *gen_action_completions PARAMS((COMPSPEC *, const char *));
|
||||
static STRINGLIST *gen_globpat_matches PARAMS((COMPSPEC *, const char *));
|
||||
static STRINGLIST *gen_wordlist_matches PARAMS((COMPSPEC *, const char *));
|
||||
static STRINGLIST *gen_shell_function_matches PARAMS((COMPSPEC *, const char *,
|
||||
static STRINGLIST *gen_matches_from_itemlist (ITEMLIST *, const char *);
|
||||
static STRINGLIST *gen_action_completions (COMPSPEC *, const char *);
|
||||
static STRINGLIST *gen_globpat_matches (COMPSPEC *, const char *);
|
||||
static STRINGLIST *gen_wordlist_matches (COMPSPEC *, const char *);
|
||||
static STRINGLIST *gen_shell_function_matches (COMPSPEC *, const char *,
|
||||
const char *,
|
||||
char *, int, WORD_LIST *,
|
||||
int, int, int *));
|
||||
static STRINGLIST *gen_command_matches PARAMS((COMPSPEC *, const char *,
|
||||
int, int, int *);
|
||||
static STRINGLIST *gen_command_matches (COMPSPEC *, const char *,
|
||||
const char *,
|
||||
char *, int, WORD_LIST *,
|
||||
int, int));
|
||||
int, int);
|
||||
|
||||
static STRINGLIST *gen_progcomp_completions PARAMS((const char *, const char *,
|
||||
static STRINGLIST *gen_progcomp_completions (const char *, const char *,
|
||||
const char *,
|
||||
int, int, int *, int *,
|
||||
COMPSPEC **));
|
||||
COMPSPEC **);
|
||||
|
||||
static char *pcomp_filename_completion_function PARAMS((const char *, int));
|
||||
static char *pcomp_filename_completion_function (const char *, int);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static SHELL_VAR *bind_comp_words PARAMS((WORD_LIST *));
|
||||
static SHELL_VAR *bind_comp_words (WORD_LIST *);
|
||||
#endif
|
||||
static void bind_compfunc_variables PARAMS((char *, int, WORD_LIST *, int, int));
|
||||
static void unbind_compfunc_variables PARAMS((int));
|
||||
static WORD_LIST *build_arg_list PARAMS((char *, const char *, const char *, WORD_LIST *, int));
|
||||
static WORD_LIST *command_line_to_word_list PARAMS((char *, int, int, int *, int *));
|
||||
static void bind_compfunc_variables (char *, int, WORD_LIST *, int, int);
|
||||
static void unbind_compfunc_variables (void *); /* XXX uw_ */
|
||||
static WORD_LIST *build_arg_list (const char *, const char *, const char *, WORD_LIST *, int);
|
||||
static WORD_LIST *command_line_to_word_list (char *, int, int, int *, int *);
|
||||
|
||||
static int compgen_compspec = 0; /* are we generating completions for compgen? */
|
||||
|
||||
#ifdef DEBUG
|
||||
static int progcomp_debug = 0;
|
||||
@@ -191,20 +187,14 @@ int pcomp_ind;
|
||||
#ifdef DEBUG
|
||||
/* Debugging code */
|
||||
static void
|
||||
#if defined (PREFER_STDARG)
|
||||
debug_printf (const char *format, ...)
|
||||
#else
|
||||
debug_printf (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (progcomp_debug == 0)
|
||||
return;
|
||||
|
||||
SH_VA_START (args, format);
|
||||
va_start (args, format);
|
||||
|
||||
fprintf (stdout, "DEBUG: ");
|
||||
vfprintf (stdout, format, args);
|
||||
@@ -219,15 +209,13 @@ debug_printf (format, va_alist)
|
||||
/* Functions to manage the item lists */
|
||||
|
||||
void
|
||||
set_itemlist_dirty (it)
|
||||
ITEMLIST *it;
|
||||
set_itemlist_dirty (ITEMLIST *it)
|
||||
{
|
||||
it->flags |= LIST_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
initialize_itemlist (itp)
|
||||
ITEMLIST *itp;
|
||||
initialize_itemlist (ITEMLIST *itp)
|
||||
{
|
||||
(*itp->list_getter) (itp);
|
||||
itp->flags |= LIST_INITIALIZED;
|
||||
@@ -235,8 +223,7 @@ initialize_itemlist (itp)
|
||||
}
|
||||
|
||||
void
|
||||
clean_itemlist (itp)
|
||||
ITEMLIST *itp;
|
||||
clean_itemlist (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
|
||||
@@ -253,12 +240,10 @@ clean_itemlist (itp)
|
||||
itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
shouldexp_filterpat (s)
|
||||
char *s;
|
||||
shouldexp_filterpat (char *s)
|
||||
{
|
||||
register char *p;
|
||||
char *p;
|
||||
|
||||
for (p = s; p && *p; p++)
|
||||
{
|
||||
@@ -274,9 +259,7 @@ shouldexp_filterpat (s)
|
||||
quote a `&' and inhibit substitution. Returns a new string. This just
|
||||
calls stringlib.c:strcreplace(). */
|
||||
static char *
|
||||
preproc_filterpat (pat, text)
|
||||
char *pat;
|
||||
const char *text;
|
||||
preproc_filterpat (const char *pat, const char *text)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
@@ -290,10 +273,7 @@ preproc_filterpat (pat, text)
|
||||
a new STRINGLIST with the matching members of SL *copied*. Any
|
||||
non-matching members of SL->list are *freed*. */
|
||||
STRINGLIST *
|
||||
filter_stringlist (sl, filterpat, text)
|
||||
STRINGLIST *sl;
|
||||
char *filterpat;
|
||||
const char *text;
|
||||
filter_stringlist (STRINGLIST *sl, char *filterpat, const char *text)
|
||||
{
|
||||
int i, m, not;
|
||||
STRINGLIST *ret;
|
||||
@@ -332,11 +312,11 @@ filter_stringlist (sl, filterpat, text)
|
||||
This understands how rl_completion_matches sets matches[0] (the lcd of the
|
||||
strings in the list, unless it's the only match). */
|
||||
STRINGLIST *
|
||||
completions_to_stringlist (matches)
|
||||
char **matches;
|
||||
completions_to_stringlist (char **matches)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
int mlen, i, n;
|
||||
int i, n;
|
||||
size_t mlen;
|
||||
|
||||
mlen = (matches == 0) ? 0 : strvec_len (matches);
|
||||
sl = strlist_create (mlen + 1);
|
||||
@@ -363,12 +343,12 @@ completions_to_stringlist (matches)
|
||||
The caller is responsible for setting ITP->flags correctly. */
|
||||
|
||||
static int
|
||||
it_init_aliases (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_aliases (ITEMLIST *itp)
|
||||
{
|
||||
#ifdef ALIAS
|
||||
alias_t **alias_list;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
STRINGLIST *sl;
|
||||
|
||||
alias_list = all_aliases ();
|
||||
@@ -385,21 +365,20 @@ it_init_aliases (itp)
|
||||
sl->list[n] = (char *)NULL;
|
||||
sl->list_size = sl->list_len = n;
|
||||
itp->slist = sl;
|
||||
free (alias_list);
|
||||
#else
|
||||
itp->slist = (STRINGLIST *)NULL;
|
||||
#endif
|
||||
free (alias_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
init_itemlist_from_varlist (itp, svfunc)
|
||||
ITEMLIST *itp;
|
||||
SVFUNC *svfunc;
|
||||
init_itemlist_from_varlist (ITEMLIST *itp, SVFUNC *svfunc)
|
||||
{
|
||||
SHELL_VAR **vlist;
|
||||
STRINGLIST *sl;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
vlist = (*svfunc) ();
|
||||
if (vlist == 0)
|
||||
@@ -418,8 +397,7 @@ init_itemlist_from_varlist (itp, svfunc)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_arrayvars (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_arrayvars (ITEMLIST *itp)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
init_itemlist_from_varlist (itp, all_array_variables);
|
||||
@@ -430,8 +408,7 @@ it_init_arrayvars (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_bindings (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_bindings (ITEMLIST *itp)
|
||||
{
|
||||
char **blist;
|
||||
STRINGLIST *sl;
|
||||
@@ -449,11 +426,11 @@ it_init_bindings (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_builtins (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_builtins (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
sl = strlist_create (num_shell_builtins);
|
||||
for (i = n = 0; i < num_shell_builtins; i++)
|
||||
@@ -466,11 +443,11 @@ it_init_builtins (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_enabled (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_enabled (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
sl = strlist_create (num_shell_builtins);
|
||||
for (i = n = 0; i < num_shell_builtins; i++)
|
||||
@@ -485,11 +462,11 @@ it_init_enabled (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_disabled (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_disabled (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
sl = strlist_create (num_shell_builtins);
|
||||
for (i = n = 0; i < num_shell_builtins; i++)
|
||||
@@ -504,16 +481,14 @@ it_init_disabled (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_exported (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_exported (ITEMLIST *itp)
|
||||
{
|
||||
init_itemlist_from_varlist (itp, all_exported_variables);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_functions (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_functions (ITEMLIST *itp)
|
||||
{
|
||||
init_itemlist_from_varlist (itp, all_visible_functions);
|
||||
return 0;
|
||||
@@ -522,11 +497,11 @@ it_init_functions (itp)
|
||||
/* Like it_init_builtins, but includes everything the help builtin looks at,
|
||||
not just builtins with an active implementing function. */
|
||||
static int
|
||||
it_init_helptopics (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_helptopics (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
sl = strlist_create (num_shell_builtins);
|
||||
for (i = n = 0; i < num_shell_builtins; i++)
|
||||
@@ -538,8 +513,7 @@ it_init_helptopics (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_hostnames (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_hostnames (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
|
||||
@@ -553,14 +527,12 @@ it_init_hostnames (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_joblist (itp, jstate)
|
||||
ITEMLIST *itp;
|
||||
int jstate;
|
||||
it_init_joblist (ITEMLIST *itp, int jstate)
|
||||
{
|
||||
#if defined (JOB_CONTROL)
|
||||
STRINGLIST *sl;
|
||||
register int i;
|
||||
register PROCESS *p;
|
||||
int i;
|
||||
PROCESS *p;
|
||||
char *s, *t;
|
||||
JOB *j;
|
||||
JOB_STATE ws; /* wanted state */
|
||||
@@ -595,32 +567,29 @@ it_init_joblist (itp, jstate)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_jobs (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_jobs (ITEMLIST *itp)
|
||||
{
|
||||
return (it_init_joblist (itp, -1));
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_running (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_running (ITEMLIST *itp)
|
||||
{
|
||||
return (it_init_joblist (itp, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_stopped (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_stopped (ITEMLIST *itp)
|
||||
{
|
||||
return (it_init_joblist (itp, 1));
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_keywords (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_keywords (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
register int i, n;
|
||||
int i;
|
||||
size_t n;
|
||||
|
||||
for (n = 0; word_token_alist[n].word; n++)
|
||||
;
|
||||
@@ -634,8 +603,7 @@ it_init_keywords (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_signals (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_signals (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
|
||||
@@ -648,16 +616,14 @@ it_init_signals (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_variables (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_variables (ITEMLIST *itp)
|
||||
{
|
||||
init_itemlist_from_varlist (itp, all_visible_variables);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_setopts (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_setopts (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
|
||||
@@ -670,8 +636,7 @@ it_init_setopts (itp)
|
||||
}
|
||||
|
||||
static int
|
||||
it_init_shopts (itp)
|
||||
ITEMLIST *itp;
|
||||
it_init_shopts (ITEMLIST *itp)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
|
||||
@@ -689,12 +654,10 @@ it_init_shopts (itp)
|
||||
new one before trying the match. TEXT is dequoted before attempting a
|
||||
match. */
|
||||
static STRINGLIST *
|
||||
gen_matches_from_itemlist (itp, text)
|
||||
ITEMLIST *itp;
|
||||
const char *text;
|
||||
gen_matches_from_itemlist (ITEMLIST *itp, const char *text)
|
||||
{
|
||||
STRINGLIST *ret, *sl;
|
||||
int tlen, i, n;
|
||||
size_t tlen, i, n;
|
||||
char *ntxt;
|
||||
|
||||
if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
|
||||
@@ -727,9 +690,7 @@ gen_matches_from_itemlist (itp, text)
|
||||
/* A wrapper for rl_filename_completion_function that dequotes the filename
|
||||
before attempting completions. */
|
||||
static char *
|
||||
pcomp_filename_completion_function (text, state)
|
||||
const char *text;
|
||||
int state;
|
||||
pcomp_filename_completion_function (const char *text, int state)
|
||||
{
|
||||
static char *dfn; /* dequoted filename */
|
||||
int iscompgen, iscompleting;
|
||||
@@ -823,9 +784,7 @@ pcomp_filename_completion_function (text, state)
|
||||
/* Functions to generate lists of matches from the actions member of CS. */
|
||||
|
||||
static STRINGLIST *
|
||||
gen_action_completions (cs, text)
|
||||
COMPSPEC *cs;
|
||||
const char *text;
|
||||
gen_action_completions (COMPSPEC *cs, const char *text)
|
||||
{
|
||||
STRINGLIST *ret, *tmatches;
|
||||
char **cmatches; /* from rl_completion_matches ... */
|
||||
@@ -885,20 +844,14 @@ gen_action_completions (cs, text)
|
||||
TEXT as a match prefix, or just go without? Currently, the code does not
|
||||
use TEXT, just globs CS->globpat and returns the results. If we do decide
|
||||
to use TEXT, we should call quote_string_for_globbing before the call to
|
||||
glob_filename (in which case we could use shell_glob_filename). */
|
||||
glob_filename (in which case we would use shell_glob_filename). */
|
||||
static STRINGLIST *
|
||||
gen_globpat_matches (cs, text)
|
||||
COMPSPEC *cs;
|
||||
const char *text;
|
||||
gen_globpat_matches (COMPSPEC *cs, const char *text)
|
||||
{
|
||||
STRINGLIST *sl;
|
||||
int gflags;
|
||||
|
||||
sl = strlist_create (0);
|
||||
gflags = glob_star ? GX_GLOBSTAR : 0;
|
||||
sl->list = glob_filename (cs->globpat, gflags);
|
||||
if (GLOB_FAILED (sl->list))
|
||||
sl->list = (char **)NULL;
|
||||
sl->list = noquote_glob_filename (cs->globpat);
|
||||
if (sl->list)
|
||||
sl->list_len = sl->list_size = strvec_len (sl->list);
|
||||
return sl;
|
||||
@@ -907,13 +860,11 @@ gen_globpat_matches (cs, text)
|
||||
/* Perform the shell word expansions on CS->words and return the results.
|
||||
Again, this ignores TEXT. */
|
||||
static STRINGLIST *
|
||||
gen_wordlist_matches (cs, text)
|
||||
COMPSPEC *cs;
|
||||
const char *text;
|
||||
gen_wordlist_matches (COMPSPEC *cs, const char *text)
|
||||
{
|
||||
WORD_LIST *l, *l2;
|
||||
STRINGLIST *sl;
|
||||
int nw, tlen;
|
||||
size_t nw, tlen;
|
||||
char *ntxt; /* dequoted TEXT to use in comparisons */
|
||||
|
||||
if (cs->words == 0 || cs->words[0] == '\0')
|
||||
@@ -933,7 +884,7 @@ gen_wordlist_matches (cs, text)
|
||||
l2 = expand_words_shellexp (l);
|
||||
dispose_words (l);
|
||||
|
||||
nw = list_length (l2);
|
||||
nw = list_length ((GENERIC_LIST *)l2);
|
||||
sl = strlist_create (nw + 1);
|
||||
|
||||
ntxt = bash_dequote_text (text);
|
||||
@@ -954,8 +905,7 @@ gen_wordlist_matches (cs, text)
|
||||
#ifdef ARRAY_VARS
|
||||
|
||||
static SHELL_VAR *
|
||||
bind_comp_words (lwords)
|
||||
WORD_LIST *lwords;
|
||||
bind_comp_words (WORD_LIST *lwords)
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
@@ -978,11 +928,7 @@ bind_comp_words (lwords)
|
||||
#endif /* ARRAY_VARS */
|
||||
|
||||
static void
|
||||
bind_compfunc_variables (line, ind, lwords, cw, exported)
|
||||
char *line;
|
||||
int ind;
|
||||
WORD_LIST *lwords;
|
||||
int cw, exported;
|
||||
bind_compfunc_variables (char *line, int ind, WORD_LIST *lwords, int cw, int exported)
|
||||
{
|
||||
char ibuf[INT_STRLEN_BOUND(int) + 1];
|
||||
char *value;
|
||||
@@ -1031,8 +977,7 @@ bind_compfunc_variables (line, ind, lwords, cw, exported)
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_compfunc_variables (exported)
|
||||
int exported;
|
||||
unbind_compfunc_variables (void *exported)
|
||||
{
|
||||
unbind_variable_noref ("COMP_LINE");
|
||||
unbind_variable_noref ("COMP_POINT");
|
||||
@@ -1059,12 +1004,7 @@ unbind_compfunc_variables (exported)
|
||||
make do with the COMP_LINE and COMP_POINT variables. */
|
||||
|
||||
static WORD_LIST *
|
||||
build_arg_list (cmd, cname, text, lwords, ind)
|
||||
char *cmd;
|
||||
const char *cname;
|
||||
const char *text;
|
||||
WORD_LIST *lwords;
|
||||
int ind;
|
||||
build_arg_list (const char *cmd, const char *cname, const char *text, WORD_LIST *lwords, int ind)
|
||||
{
|
||||
WORD_LIST *ret, *cl, *l;
|
||||
WORD_DESC *w;
|
||||
@@ -1103,27 +1043,22 @@ build_arg_list (cmd, cname, text, lwords, ind)
|
||||
variable, this does nothing if arrays are not compiled into the shell. */
|
||||
|
||||
static STRINGLIST *
|
||||
gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp)
|
||||
COMPSPEC *cs;
|
||||
const char *cmd;
|
||||
const char *text;
|
||||
char *line;
|
||||
int ind;
|
||||
WORD_LIST *lwords;
|
||||
int nw, cw;
|
||||
int *foundp;
|
||||
gen_shell_function_matches (COMPSPEC *cs, const char *cmd, const char *text,
|
||||
char *line, int ind, WORD_LIST *lwords,
|
||||
int nw, int cw, int *foundp)
|
||||
{
|
||||
char *funcname;
|
||||
STRINGLIST *sl;
|
||||
SHELL_VAR *f, *v;
|
||||
WORD_LIST *cmdlist;
|
||||
int fval, found;
|
||||
int fval, found, local_compgen;
|
||||
sh_parser_state_t ps;
|
||||
sh_parser_state_t * restrict pps;
|
||||
#if defined (ARRAY_VARS)
|
||||
ARRAY *a;
|
||||
#endif
|
||||
|
||||
local_compgen = compgen_compspec;
|
||||
found = 0;
|
||||
if (foundp)
|
||||
*foundp = found;
|
||||
@@ -1151,14 +1086,24 @@ gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp)
|
||||
pps = &ps;
|
||||
save_parser_state (pps);
|
||||
begin_unwind_frame ("gen-shell-function-matches");
|
||||
add_unwind_protect (restore_parser_state, (char *)pps);
|
||||
add_unwind_protect (dispose_words, (char *)cmdlist);
|
||||
add_unwind_protect (unbind_compfunc_variables, (char *)0);
|
||||
add_unwind_protect (uw_restore_parser_state, pps);
|
||||
add_unwind_protect (uw_dispose_words, cmdlist);
|
||||
add_unwind_protect (unbind_compfunc_variables, NULL);
|
||||
if (local_compgen == 0)
|
||||
{
|
||||
add_unwind_protect (uw_rl_set_signals, (char *)NULL);
|
||||
rl_clear_signals ();
|
||||
}
|
||||
|
||||
fval = execute_shell_function (f, cmdlist);
|
||||
|
||||
discard_unwind_frame ("gen-shell-function-matches");
|
||||
restore_parser_state (pps);
|
||||
if (local_compgen == 0)
|
||||
{
|
||||
QUIT;
|
||||
rl_set_signals ();
|
||||
}
|
||||
|
||||
found = fval != EX_NOTFOUND;
|
||||
if (fval == EX_RETRYFAIL)
|
||||
@@ -1208,17 +1153,13 @@ gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp)
|
||||
STRINGLIST from the results and return it. */
|
||||
|
||||
static STRINGLIST *
|
||||
gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw)
|
||||
COMPSPEC *cs;
|
||||
const char *cmd;
|
||||
const char *text;
|
||||
char *line;
|
||||
int ind;
|
||||
WORD_LIST *lwords;
|
||||
int nw, cw;
|
||||
gen_command_matches (COMPSPEC *cs, const char *cmd, const char *text,
|
||||
char *line, int ind, WORD_LIST *lwords,
|
||||
int nw, int cw)
|
||||
{
|
||||
char *csbuf, *cscmd, *t;
|
||||
int cmdlen, cmdsize, n, ws, we;
|
||||
int ws, we;
|
||||
size_t cmdlen, cmdsize, n;
|
||||
WORD_LIST *cmdlist, *cl;
|
||||
WORD_DESC *tw;
|
||||
STRINGLIST *sl;
|
||||
@@ -1260,7 +1201,7 @@ gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw)
|
||||
/* Now clean up and destroy everything. */
|
||||
dispose_words (cmdlist);
|
||||
free (cscmd);
|
||||
unbind_compfunc_variables (1);
|
||||
unbind_compfunc_variables ("");
|
||||
|
||||
if (csbuf == 0 || *csbuf == '\0')
|
||||
{
|
||||
@@ -1281,7 +1222,7 @@ gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw)
|
||||
we++;
|
||||
}
|
||||
t = substring (csbuf, ws, we);
|
||||
if (sl->list_len >= sl->list_size - 1)
|
||||
if (sl->list_len + 1 >= sl->list_size)
|
||||
strlist_resize (sl, sl->list_size + 16);
|
||||
sl->list[sl->list_len++] = t;
|
||||
while (csbuf[we] == '\n') we++;
|
||||
@@ -1294,18 +1235,12 @@ gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw)
|
||||
}
|
||||
|
||||
static WORD_LIST *
|
||||
command_line_to_word_list (line, llen, sentinel, nwp, cwp)
|
||||
char *line;
|
||||
int llen, sentinel, *nwp, *cwp;
|
||||
command_line_to_word_list (char *line, int llen, int sentinel, int *nwp, int *cwp)
|
||||
{
|
||||
WORD_LIST *ret;
|
||||
const char *delims;
|
||||
|
||||
#if 0
|
||||
delims = "()<>;&| \t\n"; /* shell metacharacters break words */
|
||||
#else
|
||||
delims = rl_completer_word_break_characters;
|
||||
#endif
|
||||
ret = split_at_delims (line, llen, delims, sentinel, SD_NOQUOTEDELIM|SD_COMPLETE, nwp, cwp);
|
||||
return (ret);
|
||||
}
|
||||
@@ -1313,12 +1248,8 @@ command_line_to_word_list (line, llen, sentinel, nwp, cwp)
|
||||
/* Evaluate COMPSPEC *cs and return all matches for WORD. */
|
||||
|
||||
STRINGLIST *
|
||||
gen_compspec_completions (cs, cmd, word, start, end, foundp)
|
||||
COMPSPEC *cs;
|
||||
const char *cmd;
|
||||
const char *word;
|
||||
int start, end;
|
||||
int *foundp;
|
||||
gen_compspec_completions (COMPSPEC *cs, const char *cmd, const char *word,
|
||||
int start, int end, int *foundp)
|
||||
{
|
||||
STRINGLIST *ret, *tmatches;
|
||||
char *line;
|
||||
@@ -1328,6 +1259,7 @@ gen_compspec_completions (cs, cmd, word, start, end, foundp)
|
||||
COMPSPEC *tcs;
|
||||
|
||||
found = 1;
|
||||
compgen_compspec = this_shell_builtin == compgen_builtin;
|
||||
|
||||
#ifdef DEBUG
|
||||
debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
|
||||
@@ -1522,13 +1454,15 @@ gen_compspec_completions (cs, cmd, word, start, end, foundp)
|
||||
}
|
||||
|
||||
void
|
||||
pcomp_set_readline_variables (flags, nval)
|
||||
int flags, nval;
|
||||
pcomp_set_readline_variables (int flags, int nval)
|
||||
{
|
||||
/* If the user specified that the compspec returns filenames, make
|
||||
sure that readline knows it. */
|
||||
if (flags & COPT_FILENAMES)
|
||||
rl_filename_completion_desired = nval;
|
||||
/* If we want to quote everything, not just filenames, tell readline. */
|
||||
if (flags & COPT_FULLQUOTE)
|
||||
rl_full_quoting_desired = nval;
|
||||
/* If the user doesn't want a space appended, tell readline. */
|
||||
if (flags & COPT_NOSPACE)
|
||||
rl_completion_suppress_append = nval;
|
||||
@@ -1536,6 +1470,7 @@ pcomp_set_readline_variables (flags, nval)
|
||||
option is supposed to turn it off */
|
||||
if (flags & COPT_NOQUOTE)
|
||||
rl_filename_quoting_desired = 1 - nval;
|
||||
/* Ditto */
|
||||
if (flags & COPT_NOSORT)
|
||||
rl_sort_completion_matches = 1 - nval;
|
||||
}
|
||||
@@ -1543,9 +1478,7 @@ pcomp_set_readline_variables (flags, nval)
|
||||
/* Set or unset FLAGS in the options word of the current compspec.
|
||||
SET_OR_UNSET is 1 for setting, 0 for unsetting. */
|
||||
void
|
||||
pcomp_set_compspec_options (cs, flags, set_or_unset)
|
||||
COMPSPEC *cs;
|
||||
int flags, set_or_unset;
|
||||
pcomp_set_compspec_options (COMPSPEC *cs, int flags, int set_or_unset)
|
||||
{
|
||||
if (cs == 0 && ((cs = pcomp_curcs) == 0))
|
||||
return;
|
||||
@@ -1556,18 +1489,16 @@ pcomp_set_compspec_options (cs, flags, set_or_unset)
|
||||
}
|
||||
|
||||
static STRINGLIST *
|
||||
gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
|
||||
const char *ocmd;
|
||||
const char *cmd;
|
||||
const char *word;
|
||||
int start, end;
|
||||
int *foundp, *retryp;
|
||||
COMPSPEC **lastcs;
|
||||
gen_progcomp_completions (const char *ocmd, const char *cmd, const char *word,
|
||||
int start, int end, int *foundp, int *retryp,
|
||||
COMPSPEC **lastcs)
|
||||
{
|
||||
COMPSPEC *cs, *oldcs;
|
||||
const char *oldcmd, *oldtxt;
|
||||
STRINGLIST *ret;
|
||||
|
||||
compgen_compspec = 0;
|
||||
|
||||
cs = progcomp_search (ocmd);
|
||||
|
||||
if (cs == 0 || cs == *lastcs)
|
||||
@@ -1591,7 +1522,7 @@ gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
|
||||
oldtxt = pcomp_curtxt;
|
||||
|
||||
pcomp_curcs = cs;
|
||||
pcomp_curcmd = cmd;
|
||||
pcomp_curcmd = ocmd;
|
||||
pcomp_curtxt = word;
|
||||
|
||||
ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
|
||||
@@ -1619,10 +1550,8 @@ gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs)
|
||||
bound the command currently being completed in pcomp_line (usually
|
||||
rl_line_buffer). */
|
||||
char **
|
||||
programmable_completions (cmd, word, start, end, foundp)
|
||||
const char *cmd;
|
||||
const char *word;
|
||||
int start, end, *foundp;
|
||||
programmable_completions (const char *cmd, const char *word,
|
||||
int start, int end, int *foundp)
|
||||
{
|
||||
COMPSPEC *lastcs;
|
||||
STRINGLIST *ret;
|
||||
|
||||
Reference in New Issue
Block a user