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

📄 complete.c

📁 基于的linux的oracle sqlplus替代工具
💻 C
📖 第 1 页 / 共 4 页
字号:
    temp = pathname + 1;#endif  if (temp == 0 || *temp == '\0')    return (pathname);  /* If the basename is NULL, we might have a pathname like '/usr/src/'.     Look for a previous slash and, if one is found, return the portion     following that slash.  If there's no previous slash, just return the     pathname we were passed. */  else if (temp[1] == '\0')    {      for (x = temp - 1; x > pathname; x--)        if (*x == '/')          break;      return ((*x == '/') ? x + 1 : pathname);    }  else    return ++temp;}/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we   are using it, check for and output a single character for `special'   filenames.  Return the number of characters we output. */#define PUTX(c) \    do { \      if (CTRL_CHAR (c)) \        { \          putc ('^', rl_outstream); \          putc (UNCTRL (c), rl_outstream); \          printed_len += 2; \        } \      else if (c == RUBOUT) \	{ \	  putc ('^', rl_outstream); \	  putc ('?', rl_outstream); \	  printed_len += 2; \	} \      else \	{ \	  putc (c, rl_outstream); \	  printed_len++; \	} \    } while (0)static intprint_filename (to_print, full_pathname)     char *to_print, *full_pathname;{  int printed_len = 0;#if !defined (VISIBLE_STATS)  char *s;  for (s = to_print; *s; s++)    {      PUTX (*s);    }#else    char *s, c, *new_full_pathname;  int extension_char, slen, tlen;  for (s = to_print; *s; s++)    {      PUTX (*s);    } if (rl_filename_completion_desired && rl_visible_stats)    {      /* If to_print != full_pathname, to_print is the basename of the	 path passed.  In this case, we try to expand the directory	 name before checking for the stat character. */      if (to_print != full_pathname)	{	  /* Terminate the directory name. */	  c = to_print[-1];	  to_print[-1] = '\0';	  /* If setting the last slash in full_pathname to a NUL results in	     full_pathname being the empty string, we are trying to complete	     files in the root directory.  If we pass a null string to the	     bash directory completion hook, for example, it will expand it	     to the current directory.  We just want the `/'. */	  s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/");	  if (rl_directory_completion_hook)	    (*rl_directory_completion_hook) (&s);	  slen = strlen (s);	  tlen = strlen (to_print);	  new_full_pathname = (char *)xmalloc (slen + tlen + 2);	  strcpy (new_full_pathname, s);	  new_full_pathname[slen] = '/';	  strcpy (new_full_pathname + slen + 1, to_print);	  extension_char = stat_char (new_full_pathname);	  free (new_full_pathname);	  to_print[-1] = c;	}      else	{	  s = tilde_expand (full_pathname);	  extension_char = stat_char (s);	}      free (s);      if (extension_char)	{	  putc (extension_char, rl_outstream);	  printed_len++;	}    }#endif /* VISIBLE_STATS */  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;  end = rl_point;  found_quote = delimiter = 0;  quote_char = '\0';  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++)	{	  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. */#if defined (HANDLE_MULTIBYTE)      while (rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY))#else      while (--rl_point)#endif	{	  scan = rl_line_buffer[rl_point];	  if (strchr (rl_completer_word_break_characters, 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 (rl_completer_word_break_characters, scan) != 0;      else	isbrk = strchr (rl_completer_word_break_characters, 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;  /* 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. */#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)	{	  /* 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);	}      else        strncpy (match_list[0], match_list[1], low);

⌨️ 快捷键说明

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