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

📄 init_parse.c

📁 ALSA驱动的一些调试测试工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	if (strncasecmp(attr, "step", 3) == 0) {		if (check_id_changed(space, 1))			return NULL;		type = snd_ctl_elem_info_get_type(space->ctl_info);		if (type == SND_CTL_ELEM_TYPE_INTEGER64)			val = snd_ctl_elem_info_get_step64(space->ctl_info);		else if (type == SND_CTL_ELEM_TYPE_INTEGER)			val = snd_ctl_elem_info_get_step(space->ctl_info);		else			goto empty;		goto value;	}	if (strncasecmp(attr, "items", 5) == 0) {		if (check_id_changed(space, 1))			return NULL;		if (snd_ctl_elem_info_get_type(space->ctl_info) == SND_CTL_ELEM_TYPE_ENUMERATED)			val = snd_ctl_elem_info_get_items(space->ctl_info);		else {		  empty:			res[0] = '\0';			return res;		}		goto value;	}	if (strncasecmp(attr, "value", 5) == 0) {		if (check_id_changed(space, 3))			return NULL;		return get_ctl_value(space);	}	if (strncasecmp(attr, "dBmin", 5) == 0) {		long min, max;		if (check_id_changed(space, 1))			return NULL;		if (snd_ctl_get_dB_range(snd_hctl_ctl(space->ctl_handle), space->ctl_id, &min, &max) < 0)			goto empty;		val = min;dbvalue:		sprintf(res, "%li.%02idB", (long)(val / 100), (int)abs(val % 100));		return res;	}	if (strncasecmp(attr, "dBmax", 5) == 0) {		long min, max;		if (check_id_changed(space, 1))			return NULL;		if (snd_ctl_get_dB_range(snd_hctl_ctl(space->ctl_handle), space->ctl_id, &min, &max) < 0)			goto empty;		val = max;		goto dbvalue;	}	if (strncasecmp(attr, "enums", 5) == 0) {		unsigned int idx, items;		snd_hctl_elem_t *elem;		if (check_id_changed(space, 1))			return NULL;		if (snd_ctl_elem_info_get_type(space->ctl_info) != SND_CTL_ELEM_TYPE_ENUMERATED)			goto empty;		items = snd_ctl_elem_info_get_items(space->ctl_info);		strcpy(res, "|");		for (idx = 0; idx < items; idx++) {			snd_ctl_elem_info_set_item(space->ctl_info, idx);			elem = snd_hctl_find_elem(space->ctl_handle, space->ctl_id);			if (elem == NULL)				break;			if (snd_hctl_elem_info(elem, space->ctl_info) < 0)				break;			strlcat(res, snd_ctl_elem_info_get_item_name(space->ctl_info), sizeof(res));			strlcat(res, "|", sizeof(res));		}		return res;	}	Perror(space, "unknown ctl{} attribute '%s'", attr);	return NULL;  value:  	sprintf(res, "%lli", val);  	return res;}static int elemid_set(struct space *space, const char *attr, const char *value){	unsigned int val;	void (*fcn)(snd_ctl_elem_id_t *, unsigned int);	snd_ctl_elem_iface_t iface;	int err;	if (strncasecmp(attr, "numid", 5) == 0) {		fcn = snd_ctl_elem_id_set_numid;	    	goto value;	}	if (strncasecmp(attr, "iface", 5) == 0 ||	    strncasecmp(attr, "interface", 9) == 0 ||	    strncasecmp(attr, "reset", 5) == 0 ||	    strncasecmp(attr, "search", 6) == 0) {	    	if (strlen(value) == 0 && strncasecmp(attr, "search", 6) == 0) {	    		iface = 0;	    		goto search;		}	    	for (iface = 0; iface <= SND_CTL_ELEM_IFACE_LAST; iface++) {	    		if (strcasecmp(value, snd_ctl_elem_iface_name(iface)) == 0) {			    	if (strncasecmp(attr, "reset", 5) == 0)			    		snd_ctl_elem_id_clear(space->ctl_id);			    	if (strncasecmp(attr, "search", 5) == 0) {			    	  search:			    		snd_ctl_elem_id_clear(space->ctl_id);			    		/* -1 means all */			    		snd_ctl_elem_id_set_interface(space->ctl_id, -1);			    		snd_ctl_elem_id_set_device(space->ctl_id, -1);			    		snd_ctl_elem_id_set_subdevice(space->ctl_id, -1);			    		snd_ctl_elem_id_set_name(space->ctl_id, "*");			    		snd_ctl_elem_id_set_index(space->ctl_id, -1);			    		if (strlen(value) == 0)			    			return 0;				}				snd_ctl_elem_id_set_interface(space->ctl_id, iface);				space->ctl_id_changed = ~0;			    	return 0;			}		}		Perror(space, "unknown control interface name '%s'", value);		return -EINVAL;	}	if (strncasecmp(attr, "device", 6) == 0) {		fcn = snd_ctl_elem_id_set_device;	    	goto value;	}	if (strncasecmp(attr, "subdev", 6) == 0) {		fcn = snd_ctl_elem_id_set_subdevice;	    	goto value;	}	if (strncasecmp(attr, "name", 4) == 0) {		snd_ctl_elem_id_set_name(space->ctl_id, value);	  	space->ctl_id_changed = ~0;		return 0;	}	if (strncasecmp(attr, "index", 5) == 0) {		fcn = snd_ctl_elem_id_set_index;	    	goto value;	}	if (strncasecmp(attr, "values", 6) == 0 ||	    strncasecmp(attr, "value", 5) == 0) {		err = check_id_changed(space, 1);		if (err < 0) {			Perror(space, "control element not found");			return err;		}		err = set_ctl_value(space, value, strncasecmp(attr, "values", 6) == 0);		if (err < 0) {			space->ctl_id_changed |= 2;		} else {			space->ctl_id_changed &= ~2;			snd_ctl_elem_value_set_id(space->ctl_value, space->ctl_id);			err = snd_ctl_elem_write(snd_hctl_ctl(space->ctl_handle), space->ctl_value);			if (err < 0) {				Perror(space, "value write error: %s", snd_strerror(err));				return err;			}		}	    	return err;	}	Perror(space, "unknown CTL{} attribute '%s'", attr);	return -EINVAL;  value:  	val = (unsigned int)strtol(value, NULL, 0);  	fcn(space->ctl_id, val);  	space->ctl_id_changed = ~0;  	return 0;}static int get_key(char **line, char **key, enum key_op *op, char **value){	char *linepos;	char *temp;	linepos = *line;	if (linepos == NULL && linepos[0] == '\0')		return -EINVAL;	/* skip whitespace */	while (isspace(linepos[0]) || linepos[0] == ',')		linepos++;	/* get the key */	if (linepos[0] == '\0')		return -EINVAL;	*key = linepos;	while (1) {		linepos++;		if (linepos[0] == '\0')			return -1;		if (isspace(linepos[0]))			break;		if (linepos[0] == '=')			break;		if (linepos[0] == '+')			break;		if (linepos[0] == '!')			break;		if (linepos[0] == ':')			break;	}	/* remember end of key */	temp = linepos;	/* skip whitespace after key */	while (isspace(linepos[0]))		linepos++;	if (linepos[0] == '\0')		return -EINVAL;	/* get operation type */	if (linepos[0] == '=' && linepos[1] == '=') {		*op = KEY_OP_MATCH;		linepos += 2;		dbg("operator=match");	} else if (linepos[0] == '!' && linepos[1] == '=') {		*op = KEY_OP_NOMATCH;		linepos += 2;		dbg("operator=nomatch");	} else if (linepos[0] == '+' && linepos[1] == '=') {		*op = KEY_OP_ADD;		linepos += 2;		dbg("operator=add");	} else if (linepos[0] == '=') {		*op = KEY_OP_ASSIGN;		linepos++;		dbg("operator=assign");	} else if (linepos[0] == ':' && linepos[1] == '=') {		*op = KEY_OP_ASSIGN_FINAL;		linepos += 2;		dbg("operator=assign_final");	} else		return -EINVAL;	/* terminate key */	temp[0] = '\0';	dbg("key='%s'", *key);	/* skip whitespace after operator */	while (isspace(linepos[0]))		linepos++;	if (linepos[0] == '\0')		return -EINVAL;	/* get the value*/	if (linepos[0] != '"')		return -EINVAL;	linepos++;	*value = linepos;	while (1) {		temp = strchr(linepos, '"');		if (temp && temp[-1] == '\\') {			linepos = temp + 1;			continue;		}		break;	}	if (!temp)		return -EINVAL;	temp[0] = '\0';	temp++;	dbg("value='%s'", *value);	/* move line to next key */	*line = temp;	return 0;}/* extract possible KEY{attr} */static char *get_key_attribute(struct space *space, char *str, char *res, size_t ressize){	char *pos;	char *attr;	attr = strchr(str, '{');	if (attr != NULL) {		attr++;		pos = strchr(attr, '}');		if (pos == NULL) {			Perror(space, "missing closing brace for format");			return NULL;		}		pos[0] = '\0';		strlcpy(res, attr, ressize);		pos[0] = '}';		dbg("attribute='%s'", res);		return res;	}	return NULL;}/* extract possible {attr} and move str behind it */static char *get_format_attribute(struct space *space, char **str){	char *pos;	char *attr = NULL;	if (*str[0] == '{') {		pos = strchr(*str, '}');		if (pos == NULL) {			Perror(space, "missing closing brace for format");			return NULL;		}		pos[0] = '\0';		attr = *str+1;		*str = pos+1;		dbg("attribute='%s', str='%s'", attr, *str);	}	return attr;}/* extract possible format length and move str behind it*/static int get_format_len(struct space *space, char **str){	int num;	char *tail;	if (isdigit(*str[0])) {		num = (int) strtoul(*str, &tail, 10);		if (num > 0) {			*str = tail;			dbg("format length=%i", num);			return num;		} else {			Perror(space, "format parsing error '%s'", *str);		}	}	return -1;}static void apply_format(struct space *space, char *string, size_t maxsize){	char temp[PATH_SIZE];	char temp2[PATH_SIZE];	char *head, *tail, *pos, *cpos, *attr, *rest;	struct pair *pair;	int len;	int i;	int count;	enum subst_type {		SUBST_UNKNOWN,		SUBST_CARDINFO,		SUBST_CTL,		SUBST_RESULT,		SUBST_ATTR,		SUBST_SYSFSROOT,		SUBST_ENV,	};	static const struct subst_map {		char *name;		char fmt;		enum subst_type type;	} map[] = {		{ .name = "cardinfo",	.fmt = 'i',	.type = SUBST_CARDINFO },		{ .name = "ctl",	.fmt = 'C',	.type = SUBST_CTL },		{ .name = "result",	.fmt = 'c',	.type = SUBST_RESULT },		{ .name = "attr",	.fmt = 's',	.type = SUBST_ATTR },		{ .name = "sysfsroot",	.fmt = 'r',	.type = SUBST_SYSFSROOT },		{ .name = "env",	.fmt = 'E',	.type = SUBST_ENV },		{ NULL, '\0', 0 }	};	enum subst_type type;	const struct subst_map *subst;	head = string;	while (1) {		len = -1;		while (head[0] != '\0') {			if (head[0] == '$') {				/* substitute named variable */				if (head[1] == '\0')					break;				if (head[1] == '$') {					strlcpy(temp, head+2, sizeof(temp));					strlcpy(head+1, temp, maxsize);					head++;					continue;				}				head[0] = '\0';				for (subst = map; subst->name; subst++) {					if (strncasecmp(&head[1], subst->name, strlen(subst->name)) == 0) {						type = subst->type;						tail = head + strlen(subst->name)+1;						dbg("will substitute format name '%s'", subst->name);						goto found;					}				}			} else if (head[0] == '%') {				/* substitute format char */				if (head[1] == '\0')					break;				if (head[1] == '%') {					strlcpy(temp, head+2, sizeof(temp));					strlcpy(head+1, temp, maxsize);					head++;					continue;				}				head[0] = '\0';				tail = head+1;				len = get_format_len(space, &tail);				for (subst = map; subst->name; subst++) {					if (tail[0] == subst->fmt) {						type = subst->type;						tail++;						dbg("will substitute format char '%c'", subst->fmt);						goto found;					}				}			}			head++;		}		break;found:		attr = get_format_attribute(space, &tail);		strlcpy(temp, tail, sizeof(temp));		dbg("format=%i, string='%s', tail='%s'", type ,string, tail);		switch (type) {		case SUBST_CARDINFO:			if (attr == NULL)				Perror(space, "missing identification parametr for cardinfo");			else {				const char *value = cardinfo_get(space, attr);				if (value == NULL)					break;				strlcat(string, value, maxsize);				dbg("substitute cardinfo{%s} '%s'", attr, value);			}			break;		case SUBST_CTL:			if (attr == NULL)				Perror(space, "missing identification parametr for ctl");			else {				const char *value = elemid_get(space, attr);				if (value == NULL)					break;				strlcat(string, value, maxsize);				dbg("substitute ctl{%s} '%s'", attr, value);			}			break;		case SUBST_RESULT:			if (space->program_result == NULL)				break;			/* get part part of the result string */			i = 0;			if (attr != NULL)				i = strtoul(attr, &rest, 10);			if (i > 0) {				dbg("request part #%d of result string", i);				cpos = space->program_result;				while (--i) {					while (cpos[0] != '\0' && !isspace(cpos[0]))						cpos++;					while (isspace(cpos[0]))						cpos++;				}				if (i > 0) {					Perror(space, "requested part of result string not found");					break;				}				strlcpy(temp2, cpos, sizeof(temp2));				/* %{2+}c copies the whole string from the second part on */				if (rest[0] != '+') {					cpos = strchr(temp2, ' ');					if (cpos)						cpos[0] = '\0';				}				strlcat(string, temp2, maxsize);				dbg("substitute part of result string '%s'", temp2);			} else {				strlcat(string, space->program_result, maxsize);				dbg("substitute result string '%s'", space->program_result);			}			break;		case SUBST_ATTR:			if (attr == NULL)				Perror(space, "missing file parameter for attr");			else {				const char *value = NULL;				size_t size;				pair = value_find(space, "sysfs_device");				if (pair == NULL)					break;				value = sysfs_attr_get_value(pair->value, attr);				if (value == NULL)					break;				/* strip trailing whitespace and replace untrusted characters of sysfs value */				size = strlcpy(temp2, value, sizeof(temp2));				if (size >= sizeof(temp2))					size = sizeof(temp2)-1;				while (size > 0 && isspace(temp2[size-1]))					temp2[--size] = '\0';				count = replace_untrusted_chars(temp2);				if (count > 0)					Perror(space, "%i untrusted character(s) replaced" , count);				strlcat(string, temp2, maxsize);				dbg("substitute sysfs value '%s'", temp2);			}			break;		case SUBST_SYSFSROOT:			strlcat(string, sysfs_path, maxsize);			dbg("substitute sysfs_path '%s'", sysfs_path);			break;		case SUBST_ENV:			if (attr == NULL) {				dbg("missing attribute");				break;			}			pos = getenv(attr);			if (pos == NULL) {				dbg("env '%s' not available", attr);				break;			}			dbg("substitute env '%s=%s'", attr, pos);			strlcat(string, pos, maxsize);			break;		default:			Perror(space, "unknown substitution type=%i", type);			break;		}		/* possibly truncate to format-char specified length */		if (len != -1) {			head[len] = '\0';			dbg("truncate to %i chars, subtitution string becomes '%s'", len, head);		}		strlcat(string, temp, maxsize);	}	/* unescape strings */	head = tail = string;	while (*head != '\0') {		if (*head == '\\') {			head++;			if (*head == '\0')				break;			switch (*head) {			case 'a': *tail++ = '\a'; break;			case 'b': *tail++ = '\b'; break;			case 'n': *tail++ = '\n'; break;			case 'r': *tail++ = '\r'; break;			case 't': *tail++ = '\t'; break;			case 'v': *tail++ = '\v'; break;			case '\\': *tail++ = '\\'; break;			default: *tail++ = *head; break;			}			head++;			continue;		}		if (*head)			*tail++ = *head++;	}	*tail = 0;}static int do_match(const char *key, enum key_op op,		    const char *key_value, const char *value){	int match;	if (value == NULL)		return 0;	dbg("match %s '%s' <-> '%s'", key, key_value, value);	match = fnmatch(key_value, value, 0) == 0;	if (match && op == KEY_OP_MATCH) {		dbg("%s is true (matching value)", key);		return 1;	}	if (!match && op == KEY_OP_NOMATCH) {		dbg("%s is true (non-matching value)", key);		return 1;	}	dbg("%s is false", key);	return 0;}

⌨️ 快捷键说明

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