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

📄 bashline.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 5 页
字号:
     const char *text;     int start, end, qc, compflags;{  char **matches;  matches = (char **)NULL;  /* New posix-style command substitution or variable name? */  if (!matches && *text == '$')    {      if (qc != '\'' && text[1] == '(') /* ) */	matches = rl_completion_matches (text, command_subst_completion_function);      else	matches = rl_completion_matches (text, variable_completion_function);    }  /* If the word starts in `~', and there is no slash in the word, then     try completing this word as a username. */  if (matches == 0 && *text == '~' && mbschr (text, '/') == 0)    matches = rl_completion_matches (text, rl_username_completion_function);  /* Another one.  Why not?  If the word starts in '@', then look through     the world of known hostnames for completion first. */  if (matches == 0 && perform_hostname_completion && *text == '@')    matches = rl_completion_matches (text, hostname_completion_function);  /* And last, (but not least) if this word is in a command position, then     complete over possible command names, including aliases, functions,     and command names. */  if (matches == 0 && (compflags & DEFCOMP_CMDPOS))    {      /* If END == START and text[0] == 0, we are trying to complete an empty	 command word. */      if (no_empty_command_completion && end == start && text[0] == '\0')	{	  matches = (char **)NULL;	  rl_ignore_some_completions_function = bash_ignore_everything;	}      else	{#define CMD_IS_DIR(x)	(absolute_pathname(x) == 0 && absolute_program(x) == 0 && *(x) != '~' && test_for_directory (x))	  dot_in_path = 0;	  matches = rl_completion_matches (text, command_word_completion_function);	  /* If we are attempting command completion and nothing matches, we	     do not want readline to perform filename completion for us.  We	     still want to be able to complete partial pathnames, so set the	     completion ignore function to something which will remove	     filenames and leave directories in the match list. */	  if (matches == (char **)NULL)	    rl_ignore_some_completions_function = bash_ignore_filenames;	  else if (matches[1] == 0 && CMD_IS_DIR(matches[0]) && dot_in_path == 0)	    /* If we found a single match, without looking in the current	       directory (because it's not in $PATH), but the found name is	       also a command in the current directory, suppress appending any	       terminating character, since it's ambiguous. */	    {	      rl_completion_suppress_append = 1;	      rl_filename_completion_desired = 0;	    }	  else if (matches[0] && matches[1] && STREQ (matches[0], matches[1]) && CMD_IS_DIR (matches[0]))	    /* There are multiple instances of the same match (duplicate	       completions haven't yet been removed).  In this case, all of	       the matches will be the same, and the duplicate removal code	       will distill them all down to one.  We turn on	       rl_completion_suppress_append for the same reason as above.	       Remember: we only care if there's eventually a single unique	       completion.  If there are multiple completions this won't	       make a difference and the problem won't occur. */	    {	      rl_completion_suppress_append = 1;	      rl_filename_completion_desired = 0;	    }	}    }  /* This could be a globbing pattern, so try to expand it using pathname     expansion. */  if (!matches && glob_pattern_p (text))    {      matches = rl_completion_matches (text, glob_complete_word);      /* A glob expression that matches more than one filename is problematic.	 If we match more than one filename, punt. */      if (matches && matches[1] && rl_completion_type == TAB)	{	  strvec_dispose (matches);	  matches = (char **)0;	}    }  return (matches);}/* This is the function to call when the word to complete is in a position   where a command word can be found.  It grovels $PATH, looking for commands   that match.  It also scans aliases, function names, and the shell_builtin   table. */char *command_word_completion_function (hint_text, state)     const char *hint_text;     int state;{  static char *hint = (char *)NULL;  static char *path = (char *)NULL;  static char *val = (char *)NULL;  static char *filename_hint = (char *)NULL;  static char *dequoted_hint = (char *)NULL;  static char *directory_part = (char *)NULL;  static char **glob_matches = (char **)NULL;  static int path_index, hint_len, dequoted_len, istate, igncase;  static int mapping_over, local_index, searching_path, hint_is_dir;  static int old_glob_ignore_case, globpat;  static SHELL_VAR **varlist = (SHELL_VAR **)NULL;#if defined (ALIAS)  static alias_t **alias_list = (alias_t **)NULL;#endif /* ALIAS */  char *temp;  /* We have to map over the possibilities for command words.  If we have     no state, then make one just for that purpose. */  if (state == 0)    {      if (dequoted_hint && dequoted_hint != hint)	free (dequoted_hint);      if (hint)	free (hint);      mapping_over = searching_path = 0;      hint_is_dir = CMD_IS_DIR (hint_text);      val = (char *)NULL;      temp = rl_variable_value ("completion-ignore-case");      igncase = RL_BOOLEAN_VARIABLE_VALUE (temp);      if (glob_matches)	{	  free (glob_matches);	  glob_matches = (char **)NULL;	}      globpat = glob_pattern_p (hint_text);      /* If this is an absolute program name, do not check it against	 aliases, reserved words, functions or builtins.  We must check	 whether or not it is unique, and, if so, whether that filename	 is executable. */      if (globpat || absolute_program (hint_text))	{	  /* Perform tilde expansion on what's passed, so we don't end up	     passing filenames with tildes directly to stat(). */	  if (*hint_text == '~')	    {	      hint = bash_tilde_expand (hint_text, 0);	      directory_part = savestring (hint_text);	      temp = strchr (directory_part, '/');	      if (temp)		*temp = 0;	      else		{		  free (directory_part);		  directory_part = (char *)NULL;		}	    }	  else	    hint = savestring (hint_text);	  dequoted_hint = hint;	  /* If readline's completer found a quote character somewhere, but	     didn't set the quote character, there must have been a quote	     character embedded in the filename.  It can't be at the start of	     the filename, so we need to dequote the filename before we look	     in the file system for it. */	  if (rl_completion_found_quote && rl_completion_quote_character == 0)	    {	      dequoted_hint = bash_dequote_filename (hint, 0);	      free (hint);	      hint = dequoted_hint;	    }	  dequoted_len = hint_len = strlen (hint);	  if (filename_hint)	    free (filename_hint);	  filename_hint = savestring (hint);	  istate = 0;	  if (globpat)	    {	      mapping_over = 5;	      goto globword;	    }	  else	    {	      mapping_over = 4;	      goto inner;	    }	}      dequoted_hint = hint = savestring (hint_text);      dequoted_len = hint_len = strlen (hint);      if (rl_completion_found_quote && rl_completion_quote_character == 0)	{	  dequoted_hint = bash_dequote_filename (hint, 0);	  dequoted_len = strlen (dequoted_hint);	}            path = get_string_value ("PATH");      path_index = dot_in_path = 0;      /* Initialize the variables for each type of command word. */      local_index = 0;      if (varlist)	free (varlist);      varlist = all_visible_functions ();#if defined (ALIAS)      if (alias_list)	free (alias_list);      alias_list = all_aliases ();#endif /* ALIAS */    }  /* mapping_over says what we are currently hacking.  Note that every case     in this list must fall through when there are no more possibilities. */  switch (mapping_over)    {    case 0:			/* Aliases come first. */#if defined (ALIAS)      while (alias_list && alias_list[local_index])	{	  register char *alias;	  alias = alias_list[local_index++]->name;	  if (STREQN (alias, hint, hint_len))	    return (savestring (alias));	}#endif /* ALIAS */      local_index = 0;      mapping_over++;    case 1:			/* Then shell reserved words. */      {	while (word_token_alist[local_index].word)	  {	    register char *reserved_word;	    reserved_word = word_token_alist[local_index++].word;	    if (STREQN (reserved_word, hint, hint_len))	      return (savestring (reserved_word));	  }	local_index = 0;	mapping_over++;      }    case 2:			/* Then function names. */      while (varlist && varlist[local_index])	{	  register char *varname;	  varname = varlist[local_index++]->name;	  if (STREQN (varname, hint, hint_len))	    return (savestring (varname));	}      local_index = 0;      mapping_over++;    case 3:			/* Then shell builtins. */      for (; local_index < num_shell_builtins; local_index++)	{	  /* Ignore it if it doesn't have a function pointer or if it	     is not currently enabled. */	  if (!shell_builtins[local_index].function ||	      (shell_builtins[local_index].flags & BUILTIN_ENABLED) == 0)	    continue;	  if (STREQN (shell_builtins[local_index].name, hint, hint_len))	    {	      int i = local_index++;	      return (savestring (shell_builtins[i].name));	    }	}      local_index = 0;      mapping_over++;    }globword:  /* Limited support for completing command words with globbing chars.  Only     a single match (multiple matches that end up reducing the number of     characters in the common prefix are bad) will ever be returned on     regular completion. */  if (globpat)    {      if (state == 0)	{	  glob_ignore_case = igncase;	  glob_matches = shell_glob_filename (hint);	  glob_ignore_case = old_glob_ignore_case;	  if (GLOB_FAILED (glob_matches) || glob_matches == 0)	    {	      glob_matches = (char **)NULL;	      return ((char *)NULL);	    }	  local_index = 0;			  if (glob_matches[1] && rl_completion_type == TAB)	/* multiple matches are bad */	    return ((char *)NULL);	}      while (val = glob_matches[local_index++])        {	  if (executable_or_directory (val))	    {	      if (*hint_text == '~')		{		  temp = restore_tilde (val, directory_part);		  free (val);		  val = temp;		}	      return (val);	    }	  free (val);        }      glob_ignore_case = old_glob_ignore_case;      return ((char *)NULL);    }  /* If the text passed is a directory in the current directory, return it     as a possible match.  Executables in directories in the current     directory can be specified using relative pathnames and successfully     executed even when `.' is not in $PATH. */  if (hint_is_dir)    {      hint_is_dir = 0;	/* only return the hint text once */      return (savestring (hint_text));    }      /* Repeatedly call filename_completion_function while we have     members of PATH left.  Question:  should we stat each file?     Answer: we call executable_file () on each file. */ outer:  istate = (val != (char *)NULL);  if (istate == 0)    {      char *current_path;      /* Get the next directory from the path.  If there is none, then we	 are all done. */      if (path == 0 || path[path_index] == 0 ||	  (current_path = extract_colon_unit (path, &path_index)) == 0)	return ((char *)NULL);      searching_path = 1;      if (*current_path == 0)	{	  free (current_path);	  current_path = savestring (".");	}      if (*current_path == '~')	{	  char *t;	  t = bash_tilde_expand (current_path, 0);	  free (current_path);	  current_path = t;	}      if (current_path[0] == '.' && current_path[1] == '\0')	dot_in_path = 1;      if (filename_hint)	free (filename_hint);      filename_hint = sh_makepath (current_path, hint, 0);      free (current_path);		/* XXX */    } inner:  val = rl_filename_completion_function (filename_hint, istate);  istate = 1;  if (val == 0)    {      /* If the hint text is an absolute program, then don't bother	 searching through PATH. */      if (absolute_program (hint))	return ((char *)NULL);      goto outer;    }  else    {      int match, freetemp;      if (absolute_program (hint))	{	  if (igncase == 0)	    match = strncmp (val, hint, hint_len) == 0;	  else	    match = strncasecmp (val, hint, hint_len) == 0;	  /* If we performed tilde expansion, restore the original	     filename. */	  if (*hint_text == '~')	    temp = restore_tilde (val, directory_part);	  else	    temp = savestring (val);	  freetemp = 1;	}      else	{	  temp = strrchr (val, '/');	  if (temp)	    {	      temp++;	      if (igncase == 0)		freetemp = match = strncmp (temp, hint, hint_len) == 0;	      else		freetemp = match = strncasecmp (temp, hint, hint_len) == 0;	      if (match)		temp = savestring (temp);	    }	  else	    freetemp = match = 0;	}#if 0      /* If we have found a match, and it is an executable file or a	 directory name, return it. */      if (match && executable_or_directory (val))#else      /* If we have found a match, and it is an executable file, return it.	 We don't return directory names when searching $PATH, since the	 bash execution code won't find executables in directories which	 appear in directories in $PATH when they're specified using	 relative pathnames. */      if (match && (searching_path ? executable_file (val) : executable_or_directory (val)))#endif	{	  free (val);	  val = "";		/* So it won't be NULL. */	  return (temp);	}      else	{	  if (freetemp)	    free (temp);	  free (val);	  goto inner;

⌨️ 快捷键说明

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