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

📄 iwordexp.c

📁 Intercom 是一个 Unix系统上灵活的语音传输软件。支持标准音频压缩比如GSM, G.711, and G.72x和其他音频编码。Intercom专为高速网络设计来传输高品质的语音
💻 C
📖 第 1 页 / 共 4 页
字号:
      *(*expr)++ = 0;      if (eval_expr (digit, result))	return WRDE_SYNTAX;      return 0;    case '+':	/* Positive value */      ++digit;      break;    case '-':	/* Negative value */      ++digit;      sgn = -1;      break;    default:      if (!isdigit (*digit))	return WRDE_SYNTAX;    }  *result = 0;  for (; *digit && isdigit (*digit); ++digit)    *result = (*result * 10) + (*digit - '0');  *expr = digit;  *result *= sgn;  return 0;}static intinternal_functioneval_expr_multdiv (char **expr, long int *result){  long int arg;  /* Read a Value */  if (eval_expr_val (expr, result) != 0)    return WRDE_SYNTAX;  while (**expr)    {      /* Skip white space */      for (; *expr && **expr && isspace (**expr); ++(*expr));      if (**expr == '*')	{	  ++(*expr);	  if (eval_expr_val (expr, &arg) != 0)	    return WRDE_SYNTAX;	  *result *= arg;	}      else if (**expr == '/')	{	  ++(*expr);	  if (eval_expr_val (expr, &arg) != 0)	    return WRDE_SYNTAX;	  *result /= arg;	}      else break;    }  return 0;}static intinternal_functioneval_expr (char *expr, long int *result){  long int arg;  /* Read a Multdiv */  if (eval_expr_multdiv (&expr, result) != 0)    return WRDE_SYNTAX;  while (*expr)    {      /* Skip white space */      for (; expr && *expr && isspace (*expr); ++expr);      if (*expr == '+')	{	  ++expr;	  if (eval_expr_multdiv (&expr, &arg) != 0)	    return WRDE_SYNTAX;	  *result += arg;	}      else if (*expr == '-')	{	  ++expr;	  if (eval_expr_multdiv (&expr, &arg) != 0)	    return WRDE_SYNTAX;	  *result -= arg;	}      else break;    }  return 0;}static intinternal_functionparse_arith (char **word, size_t *word_length, size_t *max_length,	     const char *words, size_t *offset, int flags, int bracket){  /* We are poised just after "$((" or "$[" */  int error;  int paren_depth = 1;  size_t expr_length;  size_t expr_maxlen;  char *expr;  expr = w_newword (&expr_length, &expr_maxlen);  for (; words[*offset]; ++(*offset))    {      switch (words[*offset])	{	case '$':	  error = parse_dollars (&expr, &expr_length, &expr_maxlen,				 words, offset, flags, NULL, NULL, NULL, 1);	  /* The ``1'' here is to tell parse_dollars not to	   * split the fields.	   */	  if (error)	    {	      free (expr);	      return error;	    }	  break;	case '`':	  (*offset)++;	  error = parse_backtick (&expr, &expr_length, &expr_maxlen,				  words, offset, flags, NULL, NULL, NULL);	  /* The first NULL here is to tell parse_backtick not to	   * split the fields.	   */	  if (error)	    {	      free (expr);	      return error;	    }	  break;	case '\\':	  error = parse_qtd_backslash (&expr, &expr_length, &expr_maxlen,				       words, offset);	  if (error)	    {	      free (expr);	      return error;	    }	  /* I think that a backslash within an	   * arithmetic expansion is bound to	   * cause an error sooner or later anyway though.	   */	  break;	case ')':	  if (--paren_depth == 0)	    {	      char result[21];	/* 21 = ceil(log10(2^64)) + 1 */	      long int numresult = 0;	      long long int convertme;	      if (bracket || words[1 + *offset] != ')')		{		  free (expr);		  return WRDE_SYNTAX;		}	      ++(*offset);	      /* Go - evaluate. */	      if (*expr && eval_expr (expr, &numresult) != 0)		{		  free (expr);		  return WRDE_SYNTAX;		}	      if (numresult < 0)		{		  convertme = -numresult;		  *word = w_addchar (*word, word_length, max_length, '-');		  if (!*word)		    {		      free (expr);		      return WRDE_NOSPACE;		    }		}	      else		convertme = numresult;	      result[20] = '\0';	      *word = w_addstr (*word, word_length, max_length,				itoa (convertme, &result[20], 10, 0));	      free (expr);	      return *word ? 0 : WRDE_NOSPACE;	    }	  expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]);	  if (expr == NULL)	    return WRDE_NOSPACE;	  break;	case ']':	  if (bracket && paren_depth == 1)	    {	      char result[21];	/* 21 = ceil(log10(2^64)) + 1 */	      long int numresult = 0;	      /* Go - evaluate. */	      if (*expr && eval_expr (expr, &numresult) != 0)		{		  free (expr);		  return WRDE_SYNTAX;		}	      result[20] = '\0';	      *word = w_addstr (*word, word_length, max_length,				itoa_word (numresult, &result[20], 10, 0));	      free (expr);	      return *word ? 0 : WRDE_NOSPACE;	    }	  free (expr);	  return WRDE_SYNTAX;	case '\n':	case ';':	case '{':	case '}':	  free (expr);	  return WRDE_BADCHAR;	case '(':	  ++paren_depth;	default:	  expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]);	  if (expr == NULL)	    return WRDE_NOSPACE;	}    }  /* Premature end */  free (expr);  return WRDE_SYNTAX;}/* Function called by child process in exec_comm() */static voidinternal_functionexec_comm_child (char *comm, int *fildes, int showerr, int noexec){  const char *args[4] = { "/bin/sh", "-c", comm, NULL };  /* Execute the command, or just check syntax? */  if (noexec)    args[1] = "-nc";  /* Redirect output.  */  dup2 (fildes[1], 1);  close (fildes[1]);  /* Redirect stderr to /dev/null if we have to.  */  if (showerr == 0)    {      int fd;      close (2);      fd = open ("/dev/null", O_WRONLY);      if (fd >= 0 && fd != 2)	{	  dup2 (fd, 2);	  close (fd);	}      }  /* Make sure the subshell doesn't field-split on our behalf. */  unsetenv ("IFS");  close (fildes[0]);  execve ("/bin/sh", (char *const *) args, environ);  /* Bad.  What now?  */  abort ();}/* Function to execute a command and retrieve the results *//* pwordexp contains NULL if field-splitting is forbidden */static intinternal_functionexec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,	   int flags, wordexp_t *pwordexp, const char *ifs,	   const char *ifs_white){  int fildes[2];  int bufsize = 128;  int buflen;  int i;  int status = 0;  size_t maxnewlines = 0;  char *buffer;  pid_t pid;  /* Don't fork() unless necessary */  if (!comm || !*comm)    return 0;  if (pipe (fildes))    /* Bad */    return WRDE_NOSPACE;  if ((pid = fork ()) < 0)    {      /* Bad */      close (fildes[0]);      close (fildes[1]);      return WRDE_NOSPACE;    }  if (pid == 0)    exec_comm_child(comm, fildes, (flags & WRDE_SHOWERR), 0);  /* Parent */  close (fildes[1]);  buffer = alloca (bufsize);  if (!pwordexp)    /* Quoted - no field splitting */    {      while (1)	{	  if ((buflen = read (fildes[0], buffer, bufsize)) < 1)	    {	      if (waitpid (pid, &status, WNOHANG) == 0)		continue;	      if ((buflen = read (fildes[0], buffer, bufsize)) < 1)		break;	    }	  maxnewlines += buflen;	  *word = w_addmem (*word, word_length, max_length, buffer, buflen);	  if (*word == NULL)	    goto no_space;	}    }  else    /* Not quoted - split fields */    {      int copying = 0;      /* 'copying' is:       *  0 when searching for first character in a field not IFS white space       *  1 when copying the text of a field       *  2 when searching for possible non-whitespace IFS       *  3 when searching for non-newline after copying field       */      while (1)	{	  if ((buflen = read (fildes[0], buffer, bufsize)) < 1)	    {	      if (waitpid (pid, &status, WNOHANG) == 0)		continue;	      if ((buflen = read (fildes[0], buffer, bufsize)) < 1)		break;	    }	  for (i = 0; i < buflen; ++i)	    {	      if (strchr (ifs, buffer[i]) != NULL)		{		  /* Current character is IFS */		  if (strchr (ifs_white, buffer[i]) == NULL)		    {		      /* Current character is IFS but not whitespace */		      if (copying == 2)			{			  /*            current character			   *                   |			   *                   V			   * eg: text<space><comma><space>moretext			   *			   * So, strip whitespace IFS (like at the start)			   */			  copying = 0;			  continue;			}		      copying = 0;		      /* fall through and delimit field.. */		    }		  else		    {		      if (buffer[i] == '\n')			{			  /* Current character is (IFS) newline */			  /* If copying a field, this is the end of it,			     but maybe all that's left is trailing newlines.			     So start searching for a non-newline. */			  if (copying == 1)			    copying = 3;			  continue;			}		      else			{			  /* Current character is IFS white space, but			     not a newline */			  /* If not either copying a field or searching			     for non-newline after a field, ignore it */			  if (copying != 1 && copying != 3)			    continue;			  /* End of field (search for non-ws IFS afterwards) */			  copying = 2;			}		    }		  /* First IFS white space (non-newline), or IFS non-whitespace.		   * Delimit the field.  Nulls are converted by w_addword. */		  if (w_addword (pwordexp, *word) == WRDE_NOSPACE)		    goto no_space;		  *word = w_newword (word_length, max_length);		  maxnewlines = 0;		  /* fall back round the loop.. */		}	      else		{		  /* Not IFS character */		  if (copying == 3)		    {		      /* Nothing but (IFS) newlines since the last field,		         so delimit it here before starting new word */		      if (w_addword (pwordexp, *word) == WRDE_NOSPACE)			goto no_space;		      *word = w_newword (word_length, max_length);		    }		  copying = 1;		  if (buffer[i] == '\n') /* happens if newline not in IFS */		    maxnewlines++;		  else		    maxnewlines = 0;		  *word = w_addchar (*word, word_length, max_length,				     buffer[i]);		  if (*word == NULL)		    goto no_space;		}	    }	}    }  /* Chop off trailing newlines (required by POSIX.2)  */  /* Ensure we don't go back further than the beginning of the     substitution (i.e. remove maxnewlines bytes at most) */  while (maxnewlines-- != 0 &&         *word_length > 0 && (*word)[*word_length - 1] == '\n')    {      (*word)[--*word_length] = '\0';      /* If the last word was entirely newlines, turn it into a new word       * which can be ignored if there's nothing following it. */      if (*word_length == 0)	{	  free (*word);	  *word = w_newword (word_length, max_length);	  break;	}    }  close (fildes[0]);  /* Check for syntax error (re-execute but with "-n" flag) */  if (buflen < 1 && status != 0)    {      if ((pid = fork ()) < 0)	{	  /* Bad */	  return WRDE_NOSPACE;	}      if (pid == 0)	{          fildes[0] = fildes[1] = -1;	  exec_comm_child(comm, fildes, 0, 1);	}      if (waitpid (pid, &status, 0) == pid && status != 0)	return WRDE_SYNTAX;    }  return 0;no_space:  kill (pid, SIGKILL);  waitpid (pid, NULL, 0);  close (fildes[0]);  return WRDE_NOSPACE;}static intinternal_functionparse_comm (char **word, size_t *word_length, size_t *max_length,	    const char *words, size_t *offset, int flags, wordexp_t *pwordexp,	    const char *ifs, const char *ifs_white){  /* We are poised just after "$(" */  int paren_depth = 1;  int error = 0;  int quoted = 0; /* 1 for singly-quoted, 2 for doubly-quoted */  size_t comm_length;  size_t comm_maxlen;  char *comm = w_newword (&comm_length, &comm_maxlen);  for (; words[*offset]; ++(*offset))    {      switch (words[*offset])	{	case '\'':	  if (quoted == 0)	    quoted = 1;	  else if (quoted == 1)	    quoted = 0;	  break;	case '"':	  if (quoted == 0)	    quoted = 2;	  else if (quoted == 2)	    quoted = 0;	  break;	case ')':	  if (!quoted && --paren_depth == 0)	    {	      /* Go -- give script to the shell */	      if (comm)		{		  error = exec_comm (comm, word, word_length, max_length,				     flags, pwordexp, ifs, ifs_white);		  free (comm);		}	      return error;	    }	  /* This is just part of the script */	  break;	case '(':	  if (!quoted)	    ++paren_depth;	}      comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]);      if (comm == NULL)	return WRDE_NOSPACE;    }  /* Premature end */  if (comm)    free (comm);  return WRDE_SYNTAX;}static intinternal_functionparse_param (char **word, size_t *word_length, size_t *max_length,	     const char *words, size_t *offset, int flags, wordexp_t *pwordexp,	     const char *ifs, const char *ifs_white, int quoted){  /* We are poised just after "$" */  enum action  {    ACT_NONE,    ACT_RP_SHORT_LEFT = '#',    ACT_RP_LONG_LEFT = 'L',    ACT_RP_SHORT_RIGHT = '%',    ACT_RP_LONG_RIGHT = 'R',    ACT_NULL_ERROR = '?',    ACT_NULL_SUBST = '-',    ACT_NONNULL_SUBST = '+',    ACT_NULL_ASSIGN = '='  };  size_t env_length;

⌨️ 快捷键说明

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