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

📄 braces.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 2 页
字号:
/* braces.c -- code for doing word expansion in curly braces. *//* Copyright (C) 1987-2009 Free Software Foundation, Inc.   This file is part of GNU Bash, the Bourne Again SHell.   Bash is free software: you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation, either version 3 of the License, or   (at your option) any later version.   Bash is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with Bash.  If not, see <http://www.gnu.org/licenses/>.*//* Stuff in curly braces gets expanded before all other shell expansions. */#include "config.h"#if defined (BRACE_EXPANSION)#if defined (HAVE_UNISTD_H)#  ifdef _MINIX#    include <sys/types.h>#  endif#  include <unistd.h>#endif#include "bashansi.h"#if defined (SHELL)#  include "shell.h"#endif /* SHELL */#include "general.h"#include "shmbutil.h"#include "chartypes.h"#define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n')#define BRACE_SEQ_SPECIFIER	".."extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));/* Basic idea:   Segregate the text into 3 sections: preamble (stuff before an open brace),   postamble (stuff after the matching close brace) and amble (stuff after   preamble, and before postamble).  Expand amble, and then tack on the   expansions to preamble.  Expand postamble, and tack on the expansions to   the result so far. *//* The character which is used to separate arguments. */static const int brace_arg_separator = ',';#if defined (__P)static int brace_gobbler __P((char *, size_t, int *, int));static char **expand_amble __P((char *, size_t, int));static char **expand_seqterm __P((char *, size_t));static char **mkseq __P((intmax_t, intmax_t, int, int, int));static char **array_concat __P((char **, char **));#elsestatic int brace_gobbler ();static char **expand_amble ();static char **expand_seqterm ();static char **mkseq();static char **array_concat ();#endif#if 0static voiddump_result (a)     char **a;{  int i;  for (i = 0; a[i]; i++)    printf ("dump_result: a[%d] = -%s-\n", i, a[i]);}#endif/* Return an array of strings; the brace expansion of TEXT. */char **brace_expand (text)     char *text;{  register int start;  size_t tlen;  char *preamble, *postamble, *amble;  size_t alen;  char **tack, **result;  int i, j, c, c1;  DECLARE_MBSTATE;  /* Find the text of the preamble. */  tlen = strlen (text);  i = 0;#if defined (CSH_BRACE_COMPAT)  c = brace_gobbler (text, tlen, &i, '{');	/* } */#else  /* Make sure that when we exit this loop, c == 0 or text[i] begins a     valid brace expansion sequence. */  do    {      c = brace_gobbler (text, tlen, &i, '{');	/* } */      c1 = c;      /* Verify that c begins a valid brace expansion word.  If it doesn't, we	 go on.  Loop stops when there are no more open braces in the word. */      if (c)	{	  start = j = i + 1;	/* { */	  c = brace_gobbler (text, tlen, &j, '}');	  if (c == 0)		/* it's not */	    {	      i++;	      c = c1;	      continue;	    }	  else			/* it is */	    {	      c = c1;	      break;	    }	}      else	break;    }  while (c);#endif /* !CSH_BRACE_COMPAT */  preamble = (char *)xmalloc (i + 1);  strncpy (preamble, text, i);  preamble[i] = '\0';  result = (char **)xmalloc (2 * sizeof (char *));  result[0] = preamble;  result[1] = (char *)NULL;  /* Special case.  If we never found an exciting character, then     the preamble is all of the text, so just return that. */  if (c != '{')    return (result);  /* Find the amble.  This is the stuff inside this set of braces. */  start = ++i;  c = brace_gobbler (text, tlen, &i, '}');  /* What if there isn't a matching close brace? */  if (c == 0)    {#if defined (NOTDEF)      /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START	 and I, then this should be an error.  Otherwise, it isn't. */      j = start;      while (j < i)	{	  if (text[j] == '\\')	    {	      j++;	      ADVANCE_CHAR (text, tlen, j);	      continue;	    }	  if (text[j] == brace_arg_separator)	    {	/* { */	      strvec_dispose (result);	      report_error ("no closing `%c' in %s", '}', text);	      throw_to_top_level ();	    }	  ADVANCE_CHAR (text, tlen, j);	}#endif      free (preamble);		/* Same as result[0]; see initialization. */      result[0] = savestring (text);      return (result);    }#if defined (SHELL)  amble = substring (text, start, i);  alen = i - start;#else  amble = (char *)xmalloc (1 + (i - start));  strncpy (amble, &text[start], (i - start));  alen = i - start;  amble[alen] = '\0';#endif#if defined (SHELL)  INITIALIZE_MBSTATE;  /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then     just return without doing any expansion.  */  j = 0;  while (amble[j])    {      if (amble[j] == '\\')	{	  j++;	  ADVANCE_CHAR (amble, alen, j);	  continue;	}      if (amble[j] == brace_arg_separator)	break;      ADVANCE_CHAR (amble, alen, j);    }  if (amble[j] == 0)    {      tack = expand_seqterm (amble, alen);      if (tack)	goto add_tack;      else	{	  free (amble);	  free (preamble);	  result[0] = savestring (text);	  return (result);	}    }#endif /* SHELL */  tack = expand_amble (amble, alen, 0);add_tack:  result = array_concat (result, tack);  free (amble);  strvec_dispose (tack);  postamble = text + i + 1;  tack = brace_expand (postamble);  result = array_concat (result, tack);  strvec_dispose (tack);  return (result);}/* Expand the text found inside of braces.  We simply try to split the   text at BRACE_ARG_SEPARATORs into separate strings.  We then brace   expand each slot which needs it, until there are no more slots which   need it. */static char **expand_amble (text, tlen, flags)     char *text;     size_t tlen;     int flags;{  char **result, **partial;  char *tem;  int start, i, c;  DECLARE_MBSTATE;  result = (char **)NULL;  start = i = 0;  c = 1;  while (c)    {      c = brace_gobbler (text, tlen, &i, brace_arg_separator);#if defined (SHELL)      tem = substring (text, start, i);#else      tem = (char *)xmalloc (1 + (i - start));      strncpy (tem, &text[start], (i - start));      tem[i- start] = '\0';#endif      partial = brace_expand (tem);      if (!result)	result = partial;      else	{	  register int lr, lp, j;	  lr = strvec_len (result);	  lp = strvec_len (partial);	  result = strvec_resize (result, lp + lr + 1);	  for (j = 0; j < lp; j++)	    result[lr + j] = partial[j];	  result[lr + j] = (char *)NULL;	  free (partial);	}      free (tem);      ADVANCE_CHAR (text, tlen, i);      start = i;    }  return (result);}#define ST_BAD	0#define ST_INT	1#define ST_CHAR	2#define ST_ZINT	3static char **mkseq (start, end, incr, type, width)     intmax_t start, end;     int incr, type, width;{  intmax_t n;  int i;  char **result, *t;  i = abs (end - start) + 1;  result = strvec_create (i + 1);  if (incr == 0)    incr = 1;    if (start > end && incr > 0)    incr = -incr;  else if (start < end && incr < 0)    incr = -incr;  /* Make sure we go through the loop at least once, so {3..3} prints `3' */  i = 0;  n = start;  do    {#if defined (SHELL)      QUIT;		/* XXX - memory leak here */#endif      if (type == ST_INT)	result[i++] = itos (n);      else if (type == ST_ZINT)	{	  int len, arg;	  arg = n;	  len = asprintf (&t, "%0*d", width, arg);	  result[i++] = t;	}      else	{

⌨️ 快捷键说明

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