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

📄 complete.c

📁 在非GUI环境下
💻 C
📖 第 1 页 / 共 5 页
字号:
  RL_UNSETSTATE(RL_STATE_COMPLETING);  return 0;}/***************************************************************//*							       *//*  Application-callable completion match generator functions  *//*							       *//***************************************************************//* Return an array of (char *) which is a list of completions for TEXT.   If there are no completions, return a NULL pointer.   The first entry in the returned array is the substitution for TEXT.   The remaining entries are the possible completions.   The array is terminated with a NULL pointer.   ENTRY_FUNCTION is a function of two args, and returns a (char *).     The first argument is TEXT.     The second is a state argument; it should be zero on the first call, and     non-zero on subsequent calls.  It returns a NULL pointer to the caller     when there are no more matches. */char **rl_completion_matches (text, entry_function)     const char *text;     rl_compentry_func_t *entry_function;{  /* Number of slots in match_list. */  int match_list_size;  /* The list of matches. */  char **match_list;  /* Number of matches actually found. */  int matches;  /* Temporary string binder. */  char *string;  matches = 0;  match_list_size = 10;  match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));  match_list[1] = (char *)NULL;  while (string = (*entry_function) (text, matches))    {      if (matches + 1 == match_list_size)	match_list = (char **)xrealloc	  (match_list, ((match_list_size += 10) + 1) * sizeof (char *));      match_list[++matches] = string;      match_list[matches + 1] = (char *)NULL;    }  /* If there were any matches, then look through them finding out the     lowest common denominator.  That then becomes match_list[0]. */  if (matches)    compute_lcd_of_matches (match_list, matches, text);  else				/* There were no matches. */    {      free (match_list);      match_list = (char **)NULL;    }  return (match_list);}/* A completion function for usernames.   TEXT contains a partial username preceded by a random   character (usually `~').  */char *rl_username_completion_function (text, state)     const char *text;     int state;{#if defined (__WIN32__) || defined (__OPENNT)  return (char *)NULL;#else /* !__WIN32__ && !__OPENNT) */  static char *username = (char *)NULL;  static struct passwd *entry;  static int namelen, first_char, first_char_loc;  char *value;  if (state == 0)    {      FREE (username);      first_char = *text;      first_char_loc = first_char == '~';      username = savestring (&text[first_char_loc]);      namelen = strlen (username);      setpwent ();    }  while (entry = getpwent ())    {      /* Null usernames should result in all users as possible completions. */      if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))	break;    }  if (entry == 0)    {      endpwent ();      return ((char *)NULL);    }  else    {      value = (char *)xmalloc (2 + strlen (entry->pw_name));      *value = *text;      strcpy (value + first_char_loc, entry->pw_name);      if (first_char == '~')	rl_filename_completion_desired = 1;      return (value);    }#endif /* !__WIN32__ && !__OPENNT */}/* Okay, now we write the entry_function for filename completion.  In the   general case.  Note that completion in the shell is a little different   because of all the pathnames that must be followed when looking up the   completion for a command. */char *rl_filename_completion_function (text, state)     const char *text;     int state;{  static DIR *directory = (DIR *)NULL;  static char *filename = (char *)NULL;  static char *dirname = (char *)NULL;  static char *users_dirname = (char *)NULL;  static int filename_len;  char *temp;  int dirlen;  struct dirent *entry;  /* If we don't have any state, then do some initialization. */  if (state == 0)    {      /* If we were interrupted before closing the directory or reading	 all of its contents, close it. */      if (directory)	{	  closedir (directory);	  directory = (DIR *)NULL;	}      FREE (dirname);      FREE (filename);      FREE (users_dirname);      filename = savestring (text);      if (*text == 0)	text = ".";      dirname = savestring (text);      temp = strrchr (dirname, '/');#if defined (__MSDOS__)      /* special hack for //X/... */      if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')        temp = strrchr (dirname + 3, '/');#endif      if (temp)	{	  strcpy (filename, ++temp);	  *temp = '\0';	}#if defined (__MSDOS__)      /* searches from current directory on the drive */      else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')        {          strcpy (filename, dirname + 2);          dirname[2] = '\0';        }#endif      else	{	  dirname[0] = '.';	  dirname[1] = '\0';	}      /* We aren't done yet.  We also support the "~user" syntax. */      /* Save the version of the directory that the user typed. */      users_dirname = savestring (dirname);      if (*dirname == '~')	{	  temp = tilde_expand (dirname);	  free (dirname);	  dirname = temp;	}      if (rl_directory_rewrite_hook)	(*rl_directory_rewrite_hook) (&dirname);      if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))	{	  free (users_dirname);	  users_dirname = savestring (dirname);	}      directory = opendir (dirname);      filename_len = strlen (filename);      rl_filename_completion_desired = 1;    }  /* At this point we should entertain the possibility of hacking wildcarded     filenames, like /usr/man/man<WILD>/te<TAB>.  If the directory name     contains globbing characters, then build an array of directories, and     then map over that list while completing. */  /* *** UNIMPLEMENTED *** */  /* Now that we have some state, we can read the directory. */  entry = (struct dirent *)NULL;  while (directory && (entry = readdir (directory)))    {      /* Special case for no filename.  If the user has disabled the         `match-hidden-files' variable, skip filenames beginning with `.'.	 All other entries except "." and ".." match. */      if (filename_len == 0)	{	  if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))	    continue;	  if (entry->d_name[0] != '.' ||	       (entry->d_name[1] &&		 (entry->d_name[1] != '.' || entry->d_name[2])))	    break;	}      else	{	  /* Otherwise, if these match up to the length of filename, then	     it is a match. */	  if (_rl_completion_case_fold)	    {	      if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&		  (((int)D_NAMLEN (entry)) >= filename_len) &&		  (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))		break;	    }	  else	    {	      if ((entry->d_name[0] == filename[0]) &&		  (((int)D_NAMLEN (entry)) >= filename_len) &&		  (strncmp (filename, entry->d_name, filename_len) == 0))		break;	    }	}    }  if (entry == 0)    {      if (directory)	{	  closedir (directory);	  directory = (DIR *)NULL;	}      if (dirname)	{	  free (dirname);	  dirname = (char *)NULL;	}      if (filename)	{	  free (filename);	  filename = (char *)NULL;	}      if (users_dirname)	{	  free (users_dirname);	  users_dirname = (char *)NULL;	}      return (char *)NULL;    }  else    {      /* dirname && (strcmp (dirname, ".") != 0) */      if (dirname && (dirname[0] != '.' || dirname[1]))	{	  if (rl_complete_with_tilde_expansion && *users_dirname == '~')	    {	      dirlen = strlen (dirname);	      temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));	      strcpy (temp, dirname);	      /* Canonicalization cuts off any final slash present.  We		 may need to add it back. */	      if (dirname[dirlen - 1] != '/')	        {	          temp[dirlen++] = '/';	          temp[dirlen] = '\0';	        }	    }	  else	    {	      dirlen = strlen (users_dirname);	      temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));	      strcpy (temp, users_dirname);	      /* Make sure that temp has a trailing slash here. */	      if (users_dirname[dirlen - 1] != '/')		temp[dirlen++] = '/';	    }	  strcpy (temp + dirlen, entry->d_name);	}      else	temp = savestring (entry->d_name);      return (temp);    }}/* An initial implementation of a menu completion function a la tcsh.  The   first time (if the last readline command was not rl_menu_complete), we   generate the list of matches.  This code is very similar to the code in   rl_complete_internal -- there should be a way to combine the two.  Then,   for each item in the list of matches, we insert the match in an undoable   fashion, with the appropriate character appended (this happens on the   second and subsequent consecutive calls to rl_menu_complete).  When we   hit the end of the match list, we restore the original unmatched text,   ring the bell, and reset the counter to zero. */intrl_menu_complete (count, ignore)     int count, ignore;{  rl_compentry_func_t *our_func;  int matching_filenames, found_quote;  static char *orig_text;  static char **matches = (char **)0;  static int match_list_index = 0;  static int match_list_size = 0;  static int orig_start, orig_end;  static char quote_char;  static int delimiter;  /* The first time through, we generate the list of matches and set things     up to insert them. */  if (rl_last_func != rl_menu_complete)    {      /* Clean up from previous call, if any. */      FREE (orig_text);      if (matches)	_rl_free_match_list (matches);      match_list_index = match_list_size = 0;      matches = (char **)NULL;      /* Only the completion entry function can change these. */      set_completion_defaults ('%');      our_func = rl_completion_entry_function			? rl_completion_entry_function			: rl_filename_completion_function;      /* We now look backwards for the start of a filename/variable word. */      orig_end = rl_point;      found_quote = delimiter = 0;      quote_char = '\0';      if (rl_point)	/* This (possibly) changes rl_point.  If it returns a non-zero char,	   we know we have an open quote. */	quote_char = _rl_find_completion_word (&found_quote, &delimiter);      orig_start = rl_point;      rl_point = orig_end;      orig_text = rl_copy_text (orig_start, orig_end);      matches = gen_completion_matches (orig_text, orig_start, orig_end,					our_func, found_quote, quote_char);      /* If we are matching filenames, the attempted completion function will	 have set rl_filename_completion_desired to a non-zero value.  The basic	 rl_filename_completion_function does this. */      matching_filenames = rl_filename_completion_desired;      if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)	{    	  rl_ding ();	  FREE (matches);	  matches = (char **)0;	  FREE (orig_text);	  orig_text = (char *)0;    	  completion_changed_buffer = 0;          return (0);	}      for (match_list_size = 0; matches[match_list_size]; match_list_size++)        ;      /* matches[0] is lcd if match_list_size > 1, but the circular buffer	 code below should take care of it. */    }  /* Now we have the list of matches.  Replace the text between     rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with     matches[match_list_index], and add any necessary closing char. */  if (matches == 0 || match_list_size == 0)     {      rl_ding ();      FREE (matches);      matches = (char **)0;      completion_changed_buffer = 0;      return (0);    }  match_list_index = (match_list_index + count) % match_list_size;  if (match_list_index < 0)    match_list_index += match_list_size;  if (match_list_index == 0 && match_list_size > 1)    {      rl_ding ();      insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);    }  else    {      insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);      append_to_match (matches[match_list_index], delimiter, quote_char,		       strcmp (orig_text, matches[match_list_index]));    }  completion_changed_buffer = 1;  return (0);}

⌨️ 快捷键说明

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