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

📄 complete.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 5 页
字号:
	  printed_len++;	}    }  return printed_len;}static char *rl_quote_filename (s, rtype, qcp)     char *s;     int rtype;     char *qcp;{  char *r;  r = (char *)xmalloc (strlen (s) + 2);  *r = *rl_completer_quote_characters;  strcpy (r + 1, s);  if (qcp)    *qcp = *rl_completer_quote_characters;  return r;}/* Find the bounds of the current word for completion purposes, and leave   rl_point set to the end of the word.  This function skips quoted   substrings (characters between matched pairs of characters in   rl_completer_quote_characters).  First we try to find an unclosed   quoted substring on which to do matching.  If one is not found, we use   the word break characters to find the boundaries of the current word.   We call an application-specific function to decide whether or not a   particular word break character is quoted; if that function returns a   non-zero result, the character does not break a word.  This function   returns the opening quote character if we found an unclosed quoted   substring, '\0' otherwise.  FP, if non-null, is set to a value saying   which (shell-like) quote characters we found (single quote, double   quote, or backslash) anywhere in the string.  DP, if non-null, is set to   the value of the delimiter character that caused a word break. */char_rl_find_completion_word (fp, dp)     int *fp, *dp;{  int scan, end, found_quote, delimiter, pass_next, isbrk;  char quote_char, *brkchars;  end = rl_point;  found_quote = delimiter = 0;  quote_char = '\0';  brkchars = 0;  if (rl_completion_word_break_hook)    brkchars = (*rl_completion_word_break_hook) ();  if (brkchars == 0)    brkchars = rl_completer_word_break_characters;  if (rl_completer_quote_characters)    {      /* We have a list of characters which can be used in pairs to	 quote substrings for the completer.  Try to find the start	 of an unclosed quoted substring. */      /* FOUND_QUOTE is set so we know what kind of quotes we found. */      for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))	{	  if (pass_next)	    {	      pass_next = 0;	      continue;	    }	  /* Shell-like semantics for single quotes -- don't allow backslash	     to quote anything in single quotes, especially not the closing	     quote.  If you don't like this, take out the check on the value	     of quote_char. */	  if (quote_char != '\'' && rl_line_buffer[scan] == '\\')	    {	      pass_next = 1;	      found_quote |= RL_QF_BACKSLASH;	      continue;	    }	  if (quote_char != '\0')	    {	      /* Ignore everything until the matching close quote char. */	      if (rl_line_buffer[scan] == quote_char)		{		  /* Found matching close.  Abandon this substring. */		  quote_char = '\0';		  rl_point = end;		}	    }	  else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))	    {	      /* Found start of a quoted substring. */	      quote_char = rl_line_buffer[scan];	      rl_point = scan + 1;	      /* Shell-like quoting conventions. */	      if (quote_char == '\'')		found_quote |= RL_QF_SINGLE_QUOTE;	      else if (quote_char == '"')		found_quote |= RL_QF_DOUBLE_QUOTE;	      else		found_quote |= RL_QF_OTHER_QUOTE;      	    }	}    }  if (rl_point == end && quote_char == '\0')    {      /* We didn't find an unclosed quoted substring upon which to do         completion, so use the word break characters to find the         substring on which to complete. */      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))	{	  scan = rl_line_buffer[rl_point];	  if (strchr (brkchars, scan) == 0)	    continue;	  /* Call the application-specific function to tell us whether	     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;  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)    {      _rl_interrupt_immediately++;      matches = (*rl_attempted_completion_function) (text, start, end);      if (_rl_interrupt_immediately > 0)	_rl_interrupt_immediately--;      if (matches || rl_attempted_completion_over)	{	  rl_attempted_completion_over = 0;	  return (matches);	}    }  /* XXX -- filename dequoting moved into rl_filename_completion_function */  matches = rl_completion_matches (text, our_func);  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 && rl_sort_completion_matches)    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)	{	  xfree (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)    xfree (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)    {      xfree (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;		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) ((char *)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

⌨️ 快捷键说明

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