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

📄 complete.c

📁 在非GUI环境下
💻 C
📖 第 1 页 / 共 5 页
字号:
	     this word break character is quoted and should be skipped. */	  if (rl_char_is_quoted_p && found_quote &&	      (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))	    continue;	  /* Convoluted code, but it avoids an n^2 algorithm with calls	     to char_is_quoted. */	  break;	}    }  /* If we are at an unquoted word break, then advance past it. */  scan = rl_line_buffer[rl_point];  /* If there is an application-specific function to say whether or not     a character is quoted and we found a quote character, let that     function decide whether or not a character is a word break, even     if it is found in rl_completer_word_break_characters.  Don't bother     if we're at the end of the line, though. */  if (scan)    {      if (rl_char_is_quoted_p)	isbrk = (found_quote == 0 ||		(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&		strchr (brkchars, scan) != 0;      else	isbrk = strchr (brkchars, scan) != 0;      if (isbrk)	{	  /* If the character that caused the word break was a quoting	     character, then remember it as the delimiter. */	  if (rl_basic_quote_characters &&	      strchr (rl_basic_quote_characters, scan) &&	      (end - rl_point) > 1)	    delimiter = scan;	  /* If the character isn't needed to determine something special	     about what kind of completion to perform, then advance past it. */	  if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)	    rl_point++;	}    }  if (fp)    *fp = found_quote;  if (dp)    *dp = delimiter;  return (quote_char);}static char **gen_completion_matches (text, start, end, our_func, found_quote, quote_char)     char *text;     int start, end;     rl_compentry_func_t *our_func;     int found_quote, quote_char;{  char **matches, *temp;  rl_completion_found_quote = found_quote;  rl_completion_quote_character = quote_char;  /* If the user wants to TRY to complete, but then wants to give     up and use the default completion function, they set the     variable rl_attempted_completion_function. */  if (rl_attempted_completion_function)    {      matches = (*rl_attempted_completion_function) (text, start, end);      if (matches || rl_attempted_completion_over)	{	  rl_attempted_completion_over = 0;	  return (matches);	}    }  /* Beware -- we're stripping the quotes here.  Do this only if we know     we are doing filename completion and the application has defined a     filename dequoting function. */  temp = (char *)NULL;  if (found_quote && our_func == rl_filename_completion_function &&      rl_filename_dequoting_function)    {      /* delete single and double quotes */      temp = (*rl_filename_dequoting_function) (text, quote_char);      text = temp;	/* not freeing text is not a memory leak */    }  matches = rl_completion_matches (text, our_func);  FREE (temp);  return matches;  }/* Filter out duplicates in MATCHES.  This frees up the strings in   MATCHES. */static char **remove_duplicate_matches (matches)     char **matches;{  char *lowest_common;  int i, j, newlen;  char dead_slot;  char **temp_array;  /* Sort the items. */  for (i = 0; matches[i]; i++)    ;  /* Sort the array without matches[0], since we need it to     stay in place no matter what. */  if (i)    qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);  /* Remember the lowest common denominator for it may be unique. */  lowest_common = savestring (matches[0]);  for (i = newlen = 0; matches[i + 1]; i++)    {      if (strcmp (matches[i], matches[i + 1]) == 0)	{	  free (matches[i]);	  matches[i] = (char *)&dead_slot;	}      else	newlen++;    }  /* We have marked all the dead slots with (char *)&dead_slot.     Copy all the non-dead entries into a new array. */  temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));  for (i = j = 1; matches[i]; i++)    {      if (matches[i] != (char *)&dead_slot)	temp_array[j++] = matches[i];    }  temp_array[j] = (char *)NULL;  if (matches[0] != (char *)&dead_slot)    free (matches[0]);  /* Place the lowest common denominator back in [0]. */  temp_array[0] = lowest_common;  /* If there is one string left, and it is identical to the     lowest common denominator, then the LCD is the string to     insert. */  if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)    {      free (temp_array[1]);      temp_array[1] = (char *)NULL;    }  return (temp_array);}/* Find the common prefix of the list of matches, and put it into   matches[0]. */static intcompute_lcd_of_matches (match_list, matches, text)     char **match_list;     int matches;     const char *text;{  register int i, c1, c2, si;  int low;		/* Count of max-matched characters. */  char *dtext;		/* dequoted TEXT, if needed */#if defined (HANDLE_MULTIBYTE)  int v;  mbstate_t ps1, ps2;  wchar_t wc1, wc2;#endif  /* If only one match, just use that.  Otherwise, compare each     member of the list with the next, finding out where they     stop matching. */  if (matches == 1)    {      match_list[0] = match_list[1];      match_list[1] = (char *)NULL;      return 1;    }  for (i = 1, low = 100000; i < matches; i++)    {#if defined (HANDLE_MULTIBYTE)      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)	{	  memset (&ps1, 0, sizeof (mbstate_t));	  memset (&ps2, 0, sizeof (mbstate_t));	}#endif      if (_rl_completion_case_fold)	{	  for (si = 0;	       (c1 = _rl_to_lower(match_list[i][si])) &&	       (c2 = _rl_to_lower(match_list[i + 1][si]));	       si++)#if defined (HANDLE_MULTIBYTE)	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)	      {		v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);		mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);		wc1 = towlower (wc1);		wc2 = towlower (wc2);		if (wc1 != wc2)		  break;		else if (v > 1)		  si += v - 1;	      }	    else#endif	    if (c1 != c2)	      break;	}      else	{	  for (si = 0;	       (c1 = match_list[i][si]) &&	       (c2 = match_list[i + 1][si]);	       si++)#if defined (HANDLE_MULTIBYTE)	    if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)	      {		mbstate_t ps_back = ps1;		if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))		  break;		else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)		  si += v - 1;	      }	    else#endif	    if (c1 != c2)	      break;	}      if (low > si)	low = si;    }  /* If there were multiple matches, but none matched up to even the     first character, and the user typed something, use that as the     value of matches[0]. */  if (low == 0 && text && *text)    {      match_list[0] = (char *)xmalloc (strlen (text) + 1);      strcpy (match_list[0], text);    }  else    {      match_list[0] = (char *)xmalloc (low + 1);      /* XXX - this might need changes in the presence of multibyte chars */      /* If we are ignoring case, try to preserve the case of the string	 the user typed in the face of multiple matches differing in case. */      if (_rl_completion_case_fold)	{	  /* We're making an assumption here:		IF we're completing filenames AND		   the application has defined a filename dequoting function AND		   we found a quote character AND		   the application has requested filename quoting		THEN		   we assume that TEXT was dequoted before checking against		   the file system and needs to be dequoted here before we		   check against the list of matches		FI */	  dtext = (char *)NULL;	  if (rl_filename_completion_desired &&	      rl_filename_dequoting_function &&	      rl_completion_found_quote &&	      rl_filename_quoting_desired)	    {	      dtext = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);	      text = dtext;	    }	  /* sort the list to get consistent answers. */	  qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);	  si = strlen (text);	  if (si <= low)	    {	      for (i = 1; i <= matches; i++)		if (strncmp (match_list[i], text, si) == 0)		  {		    strncpy (match_list[0], match_list[i], low);		    break;		  }	      /* no casematch, use first entry */	      if (i > matches)		strncpy (match_list[0], match_list[1], low);	    }	  else	    /* otherwise, just use the text the user typed. */	    strncpy (match_list[0], text, low);	  FREE (dtext);	}      else        strncpy (match_list[0], match_list[1], low);      match_list[0][low] = '\0';    }  return matches;}static intpostprocess_matches (matchesp, matching_filenames)     char ***matchesp;     int matching_filenames;{  char *t, **matches, **temp_matches;  int nmatch, i;  matches = *matchesp;  if (matches == 0)    return 0;  /* It seems to me that in all the cases we handle we would like     to ignore duplicate possiblilities.  Scan for the text to     insert being identical to the other completions. */  if (rl_ignore_completion_duplicates)    {      temp_matches = remove_duplicate_matches (matches);      free (matches);      matches = temp_matches;    }  /* If we are matching filenames, then here is our chance to     do clever processing by re-examining the list.  Call the     ignore function with the array as a parameter.  It can     munge the array, deleting matches as it desires. */  if (rl_ignore_some_completions_function && matching_filenames)    {      for (nmatch = 1; matches[nmatch]; nmatch++)	;      (void)(*rl_ignore_some_completions_function) (matches);      if (matches == 0 || matches[0] == 0)	{	  FREE (matches);	  *matchesp = (char **)0;	  return 0;        }      else	{	  /* If we removed some matches, recompute the common prefix. */	  for (i = 1; matches[i]; i++)	    ;	  if (i > 1 && i < nmatch)	    {	      t = matches[0];	      compute_lcd_of_matches (matches, i - 1, t);	      FREE (t);	    }	}    }  *matchesp = matches;  return (1);}/* A convenience function for displaying a list of strings in   columnar format on readline's output stream.  MATCHES is the list   of strings, in argv format, LEN is the number of strings in MATCHES,   and MAX is the length of the longest string in MATCHES. */voidrl_display_match_list (matches, len, max)     char **matches;     int len, max;{  int count, limit, printed_len, lines;  int i, j, k, l;  char *temp;  /* How many items of MAX length can we fit in the screen window? */  max += 2;  limit = _rl_screenwidth / max;  if (limit != 1 && (limit * max == _rl_screenwidth))    limit--;  /* Avoid a possible floating exception.  If max > _rl_screenwidth,     limit will be 0 and a divide-by-zero fault will result. */  if (limit == 0)    limit = 1;  /* How many iterations of the printing loop? */  count = (len + (limit - 1)) / limit;  /* Watch out for special case.  If LEN is less than LIMIT, then     just do the inner printing loop.	   0 < len <= limit  implies  count = 1. */  /* Sort the items if they are not already sorted. */  if (rl_ignore_completion_duplicates == 0)    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);  rl_crlf ();  lines = 0;  if (_rl_print_completions_horizontally == 0)    {      /* Print the sorted items, up-and-down alphabetically, like ls. */      for (i = 1; i <= count; i++)	{	  for (j = 0, l = i; j < limit; j++)	    {	      if (l > len || matches[l] == 0)		break;	      else		{		  temp = printable_part (matches[l]);		  printed_len = print_filename (temp, matches[l]);		  if (j + 1 < limit)		    for (k = 0; k < max - printed_len; k++)		      putc (' ', rl_outstream);		}	      l += count;	    }	  rl_crlf ();	  lines++;	  if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)	    {	      lines = _rl_internal_pager (lines);	      if (lines < 0)		return;	    }	}    }  else    {      /* Print the sorted items, across alphabetically, like ls -x. */      for (i = 1; matches[i]; i++)	{

⌨️ 快捷键说明

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