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

📄 subst.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 5 页
字号:
static inline char *string_extract_single_quoted (string, sindex)     char *string;     int *sindex;{  register int i;  size_t slen;  char *t;  DECLARE_MBSTATE;  /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;  i = *sindex;  while (string[i] && string[i] != '\'')    ADVANCE_CHAR (string, slen, i);  t = substring (string, *sindex, i);  if (string[i])    i++;  *sindex = i;  return (t);}static inline intskip_single_quoted (string, slen, sind)     const char *string;     size_t slen;     int sind;{  register int c;  DECLARE_MBSTATE;  c = sind;  while (string[c] && string[c] != '\'')    ADVANCE_CHAR (string, slen, c);  if (string[c])    c++;  return c;}/* Just like string_extract, but doesn't hack backslashes or any of   that other stuff.  Obeys CTLESC quoting.  Used to do splitting on $IFS. */static char *string_extract_verbatim (string, slen, sindex, charlist, flags)     char *string;     size_t slen;     int *sindex;     char *charlist;     int flags;{  register int i;#if defined (HANDLE_MULTIBYTE)  size_t clen;  wchar_t *wcharlist;#endif  int c;  char *temp;  DECLARE_MBSTATE;  if (charlist[0] == '\'' && charlist[1] == '\0')    {      temp = string_extract_single_quoted (string, sindex);      --*sindex;	/* leave *sindex at separator character */      return temp;    }  i = *sindex;#if 0  /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need     this only if MB_CUR_MAX > 1. */  slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;#endif#if defined (HANDLE_MULTIBYTE)  clen = strlen (charlist);  wcharlist = 0;#endif  while (c = string[i])    {#if defined (HANDLE_MULTIBYTE)      size_t mblength;#endif      if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)	{	  i += 2;	  continue;	}      /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL	 through, to protect the CTLNULs from later calls to	 remove_quoted_nulls. */      else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)	{	  i += 2;	  continue;	}#if defined (HANDLE_MULTIBYTE)      mblength = MBLEN (string + i, slen - i);      if (mblength > 1)	{	  wchar_t wc;	  mblength = mbtowc (&wc, string + i, slen - i);	  if (MB_INVALIDCH (mblength))	    {	      if (MEMBER (c, charlist))		break;	    }	  else	    {	      if (wcharlist == 0)		{		  size_t len;		  len = mbstowcs (wcharlist, charlist, 0);		  if (len == -1)		    len = 0;		  wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));		  mbstowcs (wcharlist, charlist, len + 1);		}	      if (wcschr (wcharlist, wc))		break;	    }	}      else		#endif      if (MEMBER (c, charlist))	break;      ADVANCE_CHAR (string, slen, i);    }#if defined (HANDLE_MULTIBYTE)  FREE (wcharlist);#endif  temp = substring (string, *sindex, i);  *sindex = i;  return (temp);}/* Extract the $( construct in STRING, and return a new string.   Start extracting at (SINDEX) as if we had just seen "$(".   Make (SINDEX) get the position of the matching ")". )   XFLAGS is additional flags to pass to other extraction functions. */char *extract_command_subst (string, sindex, xflags)     char *string;     int *sindex;     int xflags;{  if (string[*sindex] == LPAREN)    return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/  else    {      xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);      return (xparse_dolparen (string, string+*sindex, sindex, xflags));    }}/* Extract the $[ construct in STRING, and return a new string. (])   Start extracting at (SINDEX) as if we had just seen "$[".   Make (SINDEX) get the position of the matching "]". */char *extract_arithmetic_subst (string, sindex)     char *string;     int *sindex;{  return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/}#if defined (PROCESS_SUBSTITUTION)/* Extract the <( or >( construct in STRING, and return a new string.   Start extracting at (SINDEX) as if we had just seen "<(".   Make (SINDEX) get the position of the matching ")". */ /*))*/char *extract_process_subst (string, starter, sindex)     char *string;     char *starter;     int *sindex;{  return (extract_delimited_string (string, sindex, starter, "(", ")", 0));}#endif /* PROCESS_SUBSTITUTION */#if defined (ARRAY_VARS)/* This can be fooled by unquoted right parens in the passed string. If   each caller verifies that the last character in STRING is a right paren,   we don't even need to call extract_delimited_string. */char *extract_array_assignment_list (string, sindex)     char *string;     int *sindex;{  int slen;  char *ret;  slen = strlen (string);	/* ( */  if (string[slen - 1] == ')')   {      ret = substring (string, *sindex, slen - 1);      *sindex = slen - 1;      return ret;    }  return 0;  }#endif/* Extract and create a new string from the contents of STRING, a   character string delimited with OPENER and CLOSER.  SINDEX is   the address of an int describing the current offset in STRING;   it should point to just after the first OPENER found.  On exit,   SINDEX gets the position of the last character of the matching CLOSER.   If OPENER is more than a single character, ALT_OPENER, if non-null,   contains a character string that can also match CLOSER and thus   needs to be skipped. */static char *extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)     char *string;     int *sindex;     char *opener, *alt_opener, *closer;     int flags;{  int i, c, si;  size_t slen;  char *t, *result;  int pass_character, nesting_level, in_comment;  int len_closer, len_opener, len_alt_opener;  DECLARE_MBSTATE;  slen = strlen (string + *sindex) + *sindex;  len_opener = STRLEN (opener);  len_alt_opener = STRLEN (alt_opener);  len_closer = STRLEN (closer);  pass_character = in_comment = 0;  nesting_level = 1;  i = *sindex;  while (nesting_level)    {      c = string[i];      if (c == 0)	break;      if (in_comment)	{	  if (c == '\n')	    in_comment = 0;	  ADVANCE_CHAR (string, slen, i);	  continue;	}      if (pass_character)	/* previous char was backslash */	{	  pass_character = 0;	  ADVANCE_CHAR (string, slen, i);	  continue;	}      /* Not exactly right yet; should handle shell metacharacters and	 multibyte characters, too.  See COMMENT_BEGIN define in parse.y */      if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))	{          in_comment = 1;          ADVANCE_CHAR (string, slen, i);          continue;	}              if (c == CTLESC || c == '\\')	{	  pass_character++;	  i++;	  continue;	}      /* Process a nested command substitution, but only if we're parsing an	 arithmetic substitution. */      if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)        {          si = i + 2;          t = extract_command_subst (string, &si, flags|SX_NOALLOC);          i = si + 1;          continue;        }      /* Process a nested OPENER. */      if (STREQN (string + i, opener, len_opener))	{	  si = i + len_opener;	  t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);	  i = si + 1;	  continue;	}      /* Process a nested ALT_OPENER */      if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))	{	  si = i + len_alt_opener;	  t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);	  i = si + 1;	  continue;	}      /* If the current substring terminates the delimited string, decrement	 the nesting level. */      if (STREQN (string + i, closer, len_closer))	{	  i += len_closer - 1;	/* move to last byte of the closer */	  nesting_level--;	  if (nesting_level == 0)	    break;	}      /* Pass old-style command substitution through verbatim. */      if (c == '`')	{	  si = i + 1;	  t = string_extract (string, &si, "`", flags|SX_NOALLOC);	  i = si + 1;	  continue;	}      /* Pass single-quoted and double-quoted strings through verbatim. */      if (c == '\'' || c == '"')	{	  si = i + 1;	  i = (c == '\'') ? skip_single_quoted (string, slen, si)			  : skip_double_quoted (string, slen, si);	  continue;	}      /* move past this character, which was not special. */      ADVANCE_CHAR (string, slen, i);    }  if (c == 0 && nesting_level)    {      if (no_longjmp_on_fatal_error == 0)	{	  report_error (_("bad substitution: no closing `%s' in %s"), closer, string);	  last_command_exit_value = EXECUTION_FAILURE;	  exp_jump_to_top_level (DISCARD);	}      else	{	  *sindex = i;	  return (char *)NULL;	}    }  si = i - *sindex - len_closer + 1;  if (flags & SX_NOALLOC)    result = (char *)NULL;  else        {      result = (char *)xmalloc (1 + si);      strncpy (result, string + *sindex, si);      result[si] = '\0';    }  *sindex = i;  return (result);}/* Extract a parameter expansion expression within ${ and } from STRING.   Obey the Posix.2 rules for finding the ending `}': count braces while   skipping over enclosed quoted strings and command substitutions.   SINDEX is the address of an int describing the current offset in STRING;   it should point to just after the first `{' found.  On exit, SINDEX   gets the position of the matching `}'.  QUOTED is non-zero if this   occurs inside double quotes. *//* XXX -- this is very similar to extract_delimited_string -- XXX */static char *extract_dollar_brace_string (string, sindex, quoted, flags)     char *string;     int *sindex, quoted, flags;{  register int i, c;  size_t slen;  int pass_character, nesting_level, si, dolbrace_state;  char *result, *t;  DECLARE_MBSTATE;  pass_character = 0;  nesting_level = 1;  slen = strlen (string + *sindex) + *sindex;  /* The handling of dolbrace_state needs to agree with the code in parse.y:     parse_matched_pair() */  dolbrace_state = 0;  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))    dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM;  i = *sindex;  while (c = string[i])    {      if (pass_character)	{	  pass_character = 0;	  ADVANCE_CHAR (string, slen, i);	  continue;	}      /* CTLESCs and backslashes quote the next character. */      if (c == CTLESC || c == '\\')	{	  pass_character++;	  i++;	  continue;	}      if (string[i] == '$' && string[i+1] == LBRACE)	{	  nesting_level++;	  i += 2;	  continue;	}      if (c == RBRACE)	{	  nesting_level--;	  if (nesting_level == 0)	    break;	  i++;	  continue;	}      /* Pass the contents of old-style command substitutions through	 verbatim. */      if (c == '`')	{	  si = i + 1;	  t = string_extract (string, &si, "`", flags|SX_NOALLOC);	  i = si + 1;	  continue;	}      /* Pass the contents of new-style command substitutions and	 arithmetic substitutions through verbatim. */      if (string[i] == '$' && string[i+1] == LPAREN)	{	  si = i + 2;	  t = extract_command_subst (string, &si, flags|SX_NOALLOC);	  i = si + 1;	  continue;	}#if 0      /* Pass the contents of single-quoted and double-quoted strings	 through verbatim. */      if (c == '\'' || c == '"')	{	  si = i + 1;	  i = (c == '\'') ? skip_single_quoted (string, slen, si)			  : skip_double_quoted (string, slen, si);	  /* skip_XXX_quoted leaves index one past close quote */	  continue;	}#else	/* XXX - bash-4.2 */      /* Pass the contents of double-quoted strings through verbatim. */      if (c == '"')	{	  si = i + 1;	  i = skip_double_quoted (string, slen, si);	  /* skip_XXX_quoted leaves index one past close quote */	  continue;	}      if (c == '\'')	{/*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/	  if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))	    ADVANCE_CHAR (string, slen, i);	  else	    {	      si = i + 1;	      i = skip_single_quoted (string, slen, si);	    }          continue;	}#endif      /* move past this character, which was not special. */      ADVANCE_CHAR (string, slen, i);      /* This logic must agree with parse.y:parse_matched_pair, since they	 share the same defines. */      if (dolbrace_state == DOLBRACE_PARAM && c == '%' && (i - *sindex) > 1)

⌨️ 快捷键说明

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