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

📄 wordexp.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 4 页
字号:
	};	size_t env_length;	size_t env_maxlen;	size_t pat_length;	size_t pat_maxlen;	size_t start = *offset;	char *env;	char *pattern;	char *value = NULL;	enum action action = ACT_NONE;	int depth = 0;	int colon_seen = 0;	int seen_hash = 0;	int free_value = 0;	int pattern_is_quoted = 0;	/* 1 for singly-quoted, 2 for doubly-quoted */	int error;	int special = 0;	char buffer[21];	int brace = words[*offset] == '{';	env = w_newword(&env_length, &env_maxlen);	pattern = w_newword(&pat_length, &pat_maxlen);	if (brace)		++ * offset;	/* First collect the parameter name. */	if (words[*offset] == '#') {		seen_hash = 1;		if (!brace)			goto envsubst;		++*offset;	}	if (isalpha(words[*offset]) || words[*offset] == '_') {		/* Normal parameter name. */		do {			env = w_addchar(env, &env_length, &env_maxlen, words[*offset]);			if (env == NULL)				goto no_space;		}		while (isalnum(words[++*offset]) || words[*offset] == '_');	} else if (isdigit(words[*offset])) {		/* Numeric parameter name. */		special = 1;		do {			env = w_addchar(env, &env_length, &env_maxlen, words[*offset]);			if (env == NULL)				goto no_space;			if (!brace)				goto envsubst;		}		while (isdigit(words[++*offset]));	} else if (strchr("*@$", words[*offset]) != NULL) {		/* Special parameter. */		special = 1;		env = w_addchar(env, &env_length, &env_maxlen, words[*offset]);		if (env == NULL)			goto no_space;		++*offset;	} else {		if (brace)			goto syntax;	}	if (brace) {		/* Check for special action to be applied to the value. */		switch (words[*offset]) {		case '}':			/* Evaluate. */			goto envsubst;		case '#':			action = ACT_RP_SHORT_LEFT;			if (words[1 + *offset] == '#') {				++*offset;				action = ACT_RP_LONG_LEFT;			}			break;		case '%':			action = ACT_RP_SHORT_RIGHT;			if (words[1 + *offset] == '%') {				++*offset;				action = ACT_RP_LONG_RIGHT;			}			break;		case ':':			if (strchr("-=?+", words[1 + *offset]) == NULL)				goto syntax;			colon_seen = 1;			action = words[++*offset];			break;		case '-':		case '=':		case '?':		case '+':			action = words[*offset];			break;		default:			goto syntax;		}		/* Now collect the pattern, but don't expand it yet. */		++*offset;		for (; words[*offset]; ++(*offset)) {			switch (words[*offset]) {			case '{':				if (!pattern_is_quoted)					++depth;				break;			case '}':				if (!pattern_is_quoted) {					if (depth == 0)						goto envsubst;					--depth;				}				break;			case '\\':				if (pattern_is_quoted)					/* Quoted; treat as normal character. */					break;				/* Otherwise, it's an escape: next character is literal. */				if (words[++*offset] == '\0')					goto syntax;				pattern = w_addchar(pattern, &pat_length, &pat_maxlen, '\\');				if (pattern == NULL)					goto no_space;				break;			case '\'':				if (pattern_is_quoted == 0)					pattern_is_quoted = 1;				else if (pattern_is_quoted == 1)					pattern_is_quoted = 0;				break;			case '"':				if (pattern_is_quoted == 0)					pattern_is_quoted = 2;				else if (pattern_is_quoted == 2)					pattern_is_quoted = 0;				break;			}			pattern = w_addchar(pattern, &pat_length, &pat_maxlen,								words[*offset]);			if (pattern == NULL)				goto no_space;		}	}	/* End of input string -- remember to reparse the character that we	 * stopped at.  */	--(*offset);  envsubst:	if (words[start] == '{' && words[*offset] != '}')		goto syntax;	if (env == NULL) {		if (seen_hash) {			/* $# expands to the number of positional parameters */			buffer[20] = '\0';			value = _itoa(__libc_argc - 1, &buffer[20]);			seen_hash = 0;		} else {			/* Just $ on its own */			*offset = start - 1;			*word = w_addchar(*word, word_length, max_length, '$');			return *word ? 0 : WRDE_NOSPACE;		}	}	/* Is it a numeric parameter? */	else if (isdigit(env[0])) {		int n = atoi(env);		if (n >= __libc_argc)			/* Substitute NULL. */			value = NULL;		else			/* Replace with appropriate positional parameter. */			value = __libc_argv[n];	}	/* Is it a special parameter? */	else if (special) {		/* Is it `$$'? */		if (*env == '$') {			buffer[20] = '\0';			value = _itoa(getpid(), &buffer[20]);		}		/* Is it `${#*}' or `${#@}'? */		else if ((*env == '*' || *env == '@') && seen_hash) {			buffer[20] = '\0';			value = _itoa(__libc_argc > 0 ? __libc_argc - 1 : 0,							   &buffer[20]);			*word = w_addstr(*word, word_length, max_length, value);			free(env);			if (pattern)				free(pattern);			return *word ? 0 : WRDE_NOSPACE;		}		/* Is it `$*' or `$@' (unquoted) ? */		else if (*env == '*' || (*env == '@' && !quoted)) {			size_t plist_len = 0;			int p;			char *end;			/* Build up value parameter by parameter (copy them) */			for (p = 1; __libc_argv[p]; ++p)				plist_len += strlen(__libc_argv[p]) + 1;	/* for space */			value = malloc(plist_len);			if (value == NULL)				goto no_space;			end = value;			*end = 0;			for (p = 1; __libc_argv[p]; ++p) {				if (p > 1)					*end++ = ' ';				end = stpcpy(end, __libc_argv[p]);			}			free_value = 1;		} else {			/* Must be a quoted `$@' */			assert(*env == '@' && quoted);			/* Each parameter is a separate word ("$@") */			if (__libc_argc == 2)				value = __libc_argv[1];			else if (__libc_argc > 2) {				int p;				/* Append first parameter to current word. */				value = w_addstr(*word, word_length, max_length,								 __libc_argv[1]);				if (value == NULL || w_addword(pwordexp, value))					goto no_space;				for (p = 2; __libc_argv[p + 1]; p++) {					char *newword = strdup(__libc_argv[p]);					if (newword == NULL || w_addword(pwordexp, newword))						goto no_space;				}				/* Start a new word with the last parameter. */				*word = w_newword(word_length, max_length);				value = __libc_argv[p];			} else {				free(env);				free(pattern);				return 0;			}		}	} else		value = getenv(env);	if (value == NULL && (flags & WRDE_UNDEF)) {		/* Variable not defined. */		error = WRDE_BADVAL;		goto do_error;	}	if (action != ACT_NONE) {		int expand_pattern = 0;		/* First, find out if we need to expand pattern (i.e. if we will		 * use it). */		switch (action) {		case ACT_RP_SHORT_LEFT:		case ACT_RP_LONG_LEFT:		case ACT_RP_SHORT_RIGHT:		case ACT_RP_LONG_RIGHT:			/* Always expand for these. */			expand_pattern = 1;			break;		case ACT_NULL_ERROR:		case ACT_NULL_SUBST:		case ACT_NULL_ASSIGN:			if (!value || (!*value && colon_seen))				/* If param is unset, or set but null and a colon has been seen,				   the expansion of the pattern will be needed. */				expand_pattern = 1;			break;		case ACT_NONNULL_SUBST:			/* Expansion of word will be needed if parameter is set and not null,			   or set null but no colon has been seen. */			if (value && (*value || !colon_seen))				expand_pattern = 1;			break;		default:			assert(!"Unrecognised action!");		}		if (expand_pattern) {			/* We need to perform tilde expansion, parameter expansion,			   command substitution, and arithmetic expansion.  We also			   have to be a bit careful with wildcard characters, as			   pattern might be given to fnmatch soon.  To do this, we			   convert quotes to escapes. */			char *expanded;			size_t exp_len;			size_t exp_maxl;			char *p;			int quoted = 0;		/* 1: single quotes; 2: double */			expanded = w_newword(&exp_len, &exp_maxl);			for (p = pattern; p && *p; p++) {				size_t offset;				switch (*p) {				case '"':					if (quoted == 2)						quoted = 0;					else if (quoted == 0)						quoted = 2;					else						break;					continue;				case '\'':					if (quoted == 1)						quoted = 0;					else if (quoted == 0)						quoted = 1;					else						break;					continue;				case '*':				case '?':					if (quoted) {						/* Convert quoted wildchar to escaped wildchar. */						expanded = w_addchar(expanded, &exp_len,											 &exp_maxl, '\\');						if (expanded == NULL)							goto no_space;					}					break;				case '$':					offset = 0;					error = parse_dollars(&expanded, &exp_len, &exp_maxl, p,									  &offset, flags, NULL, NULL, NULL, 1);					if (error) {						if (free_value)							free(value);						if (expanded)							free(expanded);						goto do_error;					}					p += offset;					continue;				case '~':					if (quoted || exp_len)						break;					offset = 0;					error = parse_tilde(&expanded, &exp_len, &exp_maxl, p,										&offset, 0);					if (error) {						if (free_value)							free(value);						if (expanded)							free(expanded);						goto do_error;					}					p += offset;					continue;				case '\\':					expanded = w_addchar(expanded, &exp_len, &exp_maxl, '\\');					++p;					assert(*p);	/* checked when extracted initially */					if (expanded == NULL)						goto no_space;				}				expanded = w_addchar(expanded, &exp_len, &exp_maxl, *p);				if (expanded == NULL)					goto no_space;			}			if (pattern)				free(pattern);			pattern = expanded;		}		switch (action) {		case ACT_RP_SHORT_LEFT:		case ACT_RP_LONG_LEFT:		case ACT_RP_SHORT_RIGHT:		case ACT_RP_LONG_RIGHT:		{			char *p;			char c;			char *end;			if (value == NULL || pattern == NULL || *pattern == '\0')				break;			end = value + strlen(value);			switch (action) {			case ACT_RP_SHORT_LEFT:				for (p = value; p <= end; ++p) {					c = *p;					*p = '\0';					if (fnmatch(pattern, value, 0) != FNM_NOMATCH) {						*p = c;						if (free_value) {							char *newval = strdup(p);							if (newval == NULL) {								free(value);								goto no_space;							}							free(value);							value = newval;						} else							value = p;						break;					}					*p = c;				}				break;			case ACT_RP_LONG_LEFT:				for (p = end; p >= value; --p) {					c = *p;					*p = '\0';					if (fnmatch(pattern, value, 0) != FNM_NOMATCH) {						*p = c;						if (free_value) {							char *newval = strdup(p);							if (newval == NULL) {								free(value);								goto no_space;							}							free(value);							value = newval;						} else							value = p;						break;					}					*p = c;				}				break;			case ACT_RP_SHORT_RIGHT:				for (p = end; p >= value; --p) {					if (fnmatch(pattern, p, 0) != FNM_NOMATCH) {						char *newval;						newval = malloc(p - value + 1);						if (newval == NULL) {							if (free_value)								free(value);							goto no_space;						}						*(char *) mempcpy(newval, value, p - value) = '\0';						if (free_value)							free(value);						value = newval;						free_value = 1;						break;					}				}				break;			case ACT_RP_LONG_RIGHT:				for (p = value; p <= end; ++p) {					if (fnmatch(pattern, p, 0) != FNM_NOMATCH) {						char *newval;						newval = malloc(p - value + 1);						if (newval == NULL) {							if (free_value)								free(value);							goto no_space;						}						*(char *) mempcpy(newval, value, p - value) = '\0';						if (free_value)							free(value);						value = newval;						free_value = 1;						break;					}				}				break;			default:				break;			}			break;		}		case ACT_NULL_ERROR:			if (value && *value)				/* Substitute parameter */				break;			error = 0;			if (!colon_seen && value)				/* Substitute NULL */				;			else if (*pattern)				fprintf(stderr, "%s: %s\n", env, pattern);			else {				fprintf(stderr, "%s: parameter null or not set\n", env);				error = WRDE_BADVAL;			}			if (free_value)				free(value);			goto do_error;		case ACT_NULL_SUBST:			if (value && *value)				/* Substitute parameter */				break;

⌨️ 快捷键说明

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