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

📄 wordexp.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 4 页
字号:
			*result *= arg;		} else if (**expr == '/') {			++(*expr);			if (eval_expr_val(expr, &arg) != 0)				return WRDE_SYNTAX;			*result /= arg;		} else			break;	}	return 0;}static int eval_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 intparse_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]));				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(numresult, &result[20]));				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 voidexec_comm_child(char *comm, int *fildes, int showerr, int noexec){	const char *args[4] = { _PATH_BSHELL, "-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(_PATH_DEVNULL, 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(_PATH_BSHELL, (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 intexec_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 intparse_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 intparse_backtick(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 error;	int squoting = 0;	size_t comm_length;	size_t comm_maxlen;	char *comm = w_newword(&comm_length, &comm_maxlen);	for (; words[*offset]; ++(*offset)) {		switch (words[*offset]) {		case '`':			/* Go -- give the script to the shell */			error = exec_comm(comm, word, word_length, max_length, flags,							  pwordexp, ifs, ifs_white);			free(comm);			return error;		case '\\':			if (squoting) {				error = parse_qtd_backslash(&comm, &comm_length, &comm_maxlen,										words, offset);				if (error) {					free(comm);					return error;				}				break;			}			++(*offset);			error = parse_backslash(&comm, &comm_length, &comm_maxlen, words,								offset);			if (error) {				free(comm);				return error;			}			break;		case '\'':			squoting = 1 - squoting;		default:			comm = w_addchar(comm, &comm_length, &comm_maxlen,						  words[*offset]);			if (comm == NULL)				return WRDE_NOSPACE;		}	}	/* Premature end */	free(comm);	return WRDE_SYNTAX;}static intparse_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 = '='

⌨️ 快捷键说明

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