⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcomplete.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 3 页
字号:
/* pcomplete.c - functions to generate lists of matches for programmable completion. *//* Copyright (C) 1999-2009 Free Software Foundation, Inc.   This file is part of GNU Bash, the Bourne Again SHell.   Bash is free software: you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation, either version 3 of the License, or   (at your option) any later version.   Bash is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with Bash.  If not, see <http://www.gnu.org/licenses/>.*/#include <config.h>#if defined (PROGRAMMABLE_COMPLETION)#include "bashtypes.h"#include "posixstat.h"#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#include <signal.h>#if defined (PREFER_STDARG)#  include <stdarg.h>#else#  include <varargs.h>#endif#include <stdio.h>#include "bashansi.h"#include "bashintl.h"#include "shell.h"#include "pcomplete.h"#include "alias.h"#include "bashline.h"#include "execute_cmd.h"#include "pathexp.h"#if defined (JOB_CONTROL)#  include "jobs.h"#endif#if !defined (NSIG)#  include "trap.h"#endif#include "builtins.h"#include "builtins/common.h"#include <glob/glob.h>#include <glob/strmatch.h>#include <readline/rlconf.h>#include <readline/readline.h>#include <readline/history.h>#define PCOMP_RETRYFAIL	256#ifdef STRDUP#  undef STRDUP#endif#define STRDUP(x)	((x) ? savestring (x) : (char *)NULL)typedef SHELL_VAR **SVFUNC ();#ifndef HAVE_STRPBRKextern char *strpbrk __P((char *, char *));#endifextern int array_needs_making;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 __P((ITEMLIST *, int));static int it_init_aliases __P((ITEMLIST *));static int it_init_arrayvars __P((ITEMLIST *));static int it_init_bindings __P((ITEMLIST *));static int it_init_builtins __P((ITEMLIST *));static int it_init_disabled __P((ITEMLIST *));static int it_init_enabled __P((ITEMLIST *));static int it_init_exported __P((ITEMLIST *));static int it_init_functions __P((ITEMLIST *));static int it_init_hostnames __P((ITEMLIST *));static int it_init_jobs __P((ITEMLIST *));static int it_init_running __P((ITEMLIST *));static int it_init_stopped __P((ITEMLIST *));static int it_init_keywords __P((ITEMLIST *));static int it_init_signals __P((ITEMLIST *));static int it_init_variables __P((ITEMLIST *));static int it_init_setopts __P((ITEMLIST *));static int it_init_shopts __P((ITEMLIST *));static int shouldexp_filterpat __P((char *));static char *preproc_filterpat __P((char *, char *));static void init_itemlist_from_varlist __P((ITEMLIST *, SVFUNC *));static STRINGLIST *gen_matches_from_itemlist __P((ITEMLIST *, const char *));static STRINGLIST *gen_action_completions __P((COMPSPEC *, const char *));static STRINGLIST *gen_globpat_matches __P((COMPSPEC *, const char *));static STRINGLIST *gen_wordlist_matches __P((COMPSPEC *, const char *));static STRINGLIST *gen_shell_function_matches __P((COMPSPEC *, const char *,						   char *, int, WORD_LIST *,						   int, int, int *));static STRINGLIST *gen_command_matches __P((COMPSPEC *, const char *, char *,					    int, WORD_LIST *, int, int));static STRINGLIST *gen_progcomp_completions __P((const char *, const char *,						 const char *,						 int, int, int *, int *,						 COMPSPEC **));static char *pcomp_filename_completion_function __P((const char *, int));#if defined (ARRAY_VARS)static SHELL_VAR *bind_comp_words __P((WORD_LIST *));#endifstatic void bind_compfunc_variables __P((char *, int, WORD_LIST *, int, int));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 DEBUGstatic int progcomp_debug = 0;#endifint prog_completion_enabled = 1;/* These are used to manage the arrays of strings for possible completions. */ITEMLIST it_aliases = { 0, it_init_aliases, (STRINGLIST *)0 };ITEMLIST it_arrayvars  = { LIST_DYNAMIC, it_init_arrayvars, (STRINGLIST *)0 };ITEMLIST it_bindings  = { 0, it_init_bindings, (STRINGLIST *)0 };ITEMLIST it_builtins  = { 0, it_init_builtins, (STRINGLIST *)0 };ITEMLIST it_commands = { LIST_DYNAMIC };	/* unused */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_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_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_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };COMPSPEC *pcomp_curcs;const char *pcomp_curcmd;#ifdef DEBUG/* Debugging code */static void#if defined (PREFER_STDARG)debug_printf (const char *format, ...)#elsedebug_printf (format, va_alist)     const char *format;     va_dcl#endif{  va_list args;  if (progcomp_debug == 0)    return;  SH_VA_START (args, format);  fprintf (stdout, "DEBUG: ");  vfprintf (stdout, format, args);  fprintf (stdout, "\n");  rl_on_new_line ();  va_end (args);}#endif/* Functions to manage the item lists */voidset_itemlist_dirty (it)     ITEMLIST *it;{  it->flags |= LIST_DIRTY;}voidinitialize_itemlist (itp)     ITEMLIST *itp;{  (*itp->list_getter) (itp);  itp->flags |= LIST_INITIALIZED;  itp->flags &= ~LIST_DIRTY;}voidclean_itemlist (itp)     ITEMLIST *itp;{  STRINGLIST *sl;  sl = itp->slist;  if (sl)    {      if ((itp->flags & (LIST_DONTFREEMEMBERS|LIST_DONTFREE)) == 0)	strvec_flush (sl->list);      if ((itp->flags & LIST_DONTFREE) == 0)	free (sl->list);      free (sl);    }  itp->slist = (STRINGLIST *)NULL;  itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY);}static intshouldexp_filterpat (s)     char *s;{  register char *p;  for (p = s; p && *p; p++)    {      if (*p == '\\')	p++;      else if (*p == '&')	return 1;    }  return 0;}/* Replace any instance of `&' in PAT with TEXT.  Backslash may be used to   quote a `&' and inhibit substitution.  Returns a new string.  This just   calls stringlib.c:strcreplace(). */static char *preproc_filterpat (pat, text)     char *pat;     char *text;{  char *ret;  ret = strcreplace (pat, '&', text, 1);  return ret;}	/* Remove any match of FILTERPAT from SL.  A `&' in FILTERPAT is replaced by   TEXT.  A leading `!' in FILTERPAT negates the pattern; in this case   any member of SL->list that does *not* match will be removed.  This returns   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, *text;{  int i, m, not;  STRINGLIST *ret;  char *npat, *t;  if (sl == 0 || sl->list == 0 || sl->list_len == 0)    return sl;  npat = shouldexp_filterpat (filterpat) ? preproc_filterpat (filterpat, text) : filterpat;  not = (npat[0] == '!');  t = not ? npat + 1 : npat;  ret = strlist_create (sl->list_size);  for (i = 0; i < sl->list_len; i++)    {      m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG);      if ((not && m == FNM_NOMATCH) || (not == 0 && m != FNM_NOMATCH))	free (sl->list[i]);      else	ret->list[ret->list_len++] = sl->list[i];    }  ret->list[ret->list_len] = (char *)NULL;  if (npat != filterpat)    free (npat);  return ret;}/* Turn an array of strings returned by rl_completion_matches into a STRINGLIST.   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;{  STRINGLIST *sl;  int mlen, i, n;  mlen = (matches == 0) ? 0 : strvec_len (matches);  sl = strlist_create (mlen + 1);  if (matches == 0 || matches[0] == 0)    return sl;  if (matches[1] == 0)    {      sl->list[0] = STRDUP (matches[0]);      sl->list[sl->list_len = 1] = (char *)NULL;      return sl;    }  for (i = 1, n = 0; i < mlen; i++, n++)    sl->list[n] = STRDUP (matches[i]);  sl->list_len = n;  sl->list[n] = (char *)NULL;  return sl;}/* Functions to manage the various ITEMLISTs that we populate internally.   The caller is responsible for setting ITP->flags correctly. */static intit_init_aliases (itp)     ITEMLIST *itp;{#ifdef ALIAS  alias_t **alias_list;  register int i, n;  STRINGLIST *sl;  alias_list = all_aliases ();  if (alias_list == 0)    {      itp->slist = (STRINGLIST *)NULL;      return 0;    }  for (n = 0; alias_list[n]; n++)    ;  sl = strlist_create (n+1);  for (i = 0; i < n; i++)    sl->list[i] = STRDUP (alias_list[i]->name);  sl->list[n] = (char *)NULL;  sl->list_size = sl->list_len = n;  itp->slist = sl;#else  itp->slist = (STRINGLIST *)NULL;#endif  return 1;}static voidinit_itemlist_from_varlist (itp, svfunc)     ITEMLIST *itp;     SVFUNC *svfunc;{  SHELL_VAR **vlist;  STRINGLIST *sl;  register int i, n;  vlist = (*svfunc) ();  if (vlist == 0)    {      itp->slist = (STRINGLIST *)NULL;      return;    }      for (n = 0; vlist[n]; n++)    ;  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;  itp->slist = sl;}static intit_init_arrayvars (itp)     ITEMLIST *itp;{#if defined (ARRAY_VARS)  init_itemlist_from_varlist (itp, all_array_variables);  return 1;#else  return 0;#endif}static intit_init_bindings (itp)     ITEMLIST *itp;{  char **blist;  STRINGLIST *sl;  /* rl_funmap_names allocates blist, but not its members */  blist = (char **)rl_funmap_names ();	/* XXX fix const later */  sl = strlist_create (0);  sl->list = blist;  sl->list_size = 0;  sl->list_len = strvec_len (sl->list);  itp->flags |= LIST_DONTFREEMEMBERS;  itp->slist = sl;  return 0;}static intit_init_builtins (itp)     ITEMLIST *itp;{  STRINGLIST *sl;  register int i, n;  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;  sl->list[sl->list_len = n] = (char *)NULL;  itp->flags |= LIST_DONTFREEMEMBERS;  itp->slist = sl;  return 0;}static intit_init_enabled (itp)     ITEMLIST *itp;{  STRINGLIST *sl;  register int i, n;  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))	sl->list[n++] = shell_builtins[i].name;    }  sl->list[sl->list_len = n] = (char *)NULL;  itp->flags |= LIST_DONTFREEMEMBERS;  itp->slist = sl;  return 0;}static intit_init_disabled (itp)     ITEMLIST *itp;{  STRINGLIST *sl;  register int i, n;  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))	sl->list[n++] = shell_builtins[i].name;    }  sl->list[sl->list_len = n] = (char *)NULL;  itp->flags |= LIST_DONTFREEMEMBERS;  itp->slist = sl;  return 0;}static intit_init_exported (itp)     ITEMLIST *itp;{  init_itemlist_from_varlist (itp, all_exported_variables);  return 0;}static intit_init_functions (itp)     ITEMLIST *itp;{  init_itemlist_from_varlist (itp, all_visible_functions);  return 0;}static intit_init_hostnames (itp)     ITEMLIST *itp;{  STRINGLIST *sl;  sl = strlist_create (0);  sl->list = get_hostname_list ();  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;  return 0;}static intit_init_joblist (itp, jstate)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -