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

📄 init_parse.c

📁 ALSA驱动的一些调试测试工具
💻 C
📖 第 1 页 / 共 3 页
字号:
static int ctl_match(snd_ctl_elem_id_t *pattern, snd_ctl_elem_id_t *id){	if (snd_ctl_elem_id_get_interface(pattern) != -1 &&	    snd_ctl_elem_id_get_interface(pattern) != snd_ctl_elem_id_get_interface(id))	    	return 0;	if (snd_ctl_elem_id_get_device(pattern) != -1 &&	    snd_ctl_elem_id_get_device(pattern) != snd_ctl_elem_id_get_device(id))		return 0;	if (snd_ctl_elem_id_get_subdevice(pattern) != -1 &&	    snd_ctl_elem_id_get_subdevice(pattern) != snd_ctl_elem_id_get_subdevice(id))	    	return 0;	if (snd_ctl_elem_id_get_index(pattern) != -1 &&	    snd_ctl_elem_id_get_index(pattern) != snd_ctl_elem_id_get_index(id))	    	return 0;	if (fnmatch(snd_ctl_elem_id_get_name(pattern), snd_ctl_elem_id_get_name(id), 0) != 0)		return 0;	return 1;}staticint run_program1(struct space *space,		 const char *command0, char *result,		 size_t ressize, size_t *reslen, int log){	char *pos = strchr(command0, ' ');	int cmdlen = pos ? pos - command0 : strlen(command0);	int err, index;	snd_hctl_elem_t *elem;	snd_ctl_elem_id_t *id;		if (cmdlen == 12 && strncmp(command0, "__ctl_search", 12) == 0) {		index = 0;		if (pos)			index = strtol(pos, NULL, 0);		err = snd_ctl_elem_id_malloc(&id);		if (err < 0)			return EXIT_FAILURE;		elem = snd_hctl_first_elem(space->ctl_handle);		while (elem) {			snd_hctl_elem_get_id(elem, id);			if (!ctl_match(space->ctl_id, id))				goto next_search;			if (index > 0) {				index--;				goto next_search;			}			strlcpy(result, "0", ressize);			snd_ctl_elem_id_copy(space->ctl_id, id);			snd_ctl_elem_id_free(id);			dbg("__ctl_search found a control");			return EXIT_SUCCESS;		      next_search:			elem = snd_hctl_elem_next(elem);		}		snd_ctl_elem_id_free(id);		return EXIT_FAILURE;	}	if (cmdlen == 11 && strncmp(command0, "__ctl_count", 11) == 0) {		index = 0;		err = snd_ctl_elem_id_malloc(&id);		if (err < 0)			return EXIT_FAILURE;		elem = snd_hctl_first_elem(space->ctl_handle);		while (elem) {			snd_hctl_elem_get_id(elem, id);			if (!ctl_match(space->ctl_id, id))				goto next_count;			index++;		      next_count:			elem = snd_hctl_elem_next(elem);		}		snd_ctl_elem_id_free(id);		if (index > 0) {			snprintf(result, ressize, "%u", index);			dbg("__ctl_count found %s controls", result);			return EXIT_SUCCESS;		}		dbg("__ctl_count no match");		return EXIT_FAILURE;	}	if (cmdlen == 11 && strncmp(command0, "__ctl_write", 11) == 0) {	}	Perror(space, "unknown buildin command '%s'", command0);	return EXIT_FAILURE;}static int parse(struct space *space, const char *filename);static char *new_root_dir(const char *filename){	char *res, *tmp;	res = strdup(filename);	if (res) {		tmp = rindex(res, '/');		if (tmp)			*tmp = '\0';	}	dbg("new_root_dir '%s' '%s'", filename, res);	return res;}static int parse_line(struct space *space, char *line, size_t linesize){	char *linepos;	char *key, *value, *attr, *temp;	struct pair *pair;	enum key_op op;	int err = 0, count;	char string[PATH_SIZE];	char result[PATH_SIZE];	linepos = line;	while (*linepos != '\0') {		op = KEY_OP_UNSET;				err = get_key(&linepos, &key, &op, &value);		if (err < 0)			goto invalid;		if (strncasecmp(key, "LABEL", 5) == 0) {			if (op != KEY_OP_ASSIGN) {				Perror(space, "invalid LABEL operation");				goto invalid;			}			if (space->go_to && strcmp(space->go_to, value) == 0) {				free(space->go_to);				space->go_to = NULL;			}			continue;		}				if (space->go_to) {			dbg("skip (GOTO '%s')", space->go_to);			break;		/* not for us */		}		if (strncasecmp(key, "CTL{", 4) == 0) {			attr = get_key_attribute(space, key + 3, string, sizeof(string));			if (attr == NULL) {				Perror(space, "error parsing CTL attribute");				goto invalid;			}			if (op == KEY_OP_ASSIGN) {				strlcpy(result, value, sizeof(result));				apply_format(space, result, sizeof(result));				dbg("ctl assign: '%s' '%s'", value, attr);				err = elemid_set(space, attr, result);				if (space->program_result) {					free(space->program_result);					space->program_result = NULL;				}				snprintf(string, sizeof(string), "%i", err);				space->program_result = strdup(string);				if (err < 0 || space->program_result == NULL) {					err = 0;					break;				}			} else if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				dbg("ctl match: '%s' '%s'", value, attr);				temp = (char *)elemid_get(space, attr);				if (!do_match(key, op, value, temp))					break;			} else {				Perror(space, "invalid CTL{} operation");				goto invalid;			}			continue;		}		if (strcasecmp(key, "RESULT") == 0) {			if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				if (!do_match(key, op, value, space->program_result))					break;			} else if (op == KEY_OP_ASSIGN) {				if (space->program_result) {					free(space->program_result);					space->program_result = NULL;				}				strlcpy(string, value, sizeof(string));				apply_format(space, string, sizeof(string));				space->program_result = strdup(string);				if (space->program_result == NULL)					break; 			} else {				Perror(space, "invalid RESULT operation");				goto invalid;			}			continue;		}		if (strcasecmp(key, "PROGRAM") == 0) {			if (op == KEY_OP_UNSET)				continue;			strlcpy(string, value, sizeof(string));			apply_format(space, string, sizeof(string));			if (space->program_result) {				free(space->program_result);				space->program_result = NULL;			}			if (run_program(space, string, result, sizeof(result), NULL, space->log_run) != 0) {				dbg("PROGRAM '%s' is false", string);				if (op != KEY_OP_NOMATCH)					break;			} else {				remove_trailing_chars(result, '\n');				count = replace_untrusted_chars(result);				if (count)					info("%i untrusted character(s) replaced", count);				dbg("PROGRAM '%s' result is '%s'", string, result);				space->program_result = strdup(result);				if (space->program_result == NULL)					break;				dbg("PROGRAM returned successful");				if (op == KEY_OP_NOMATCH)					break;			}			dbg("PROGRAM key is true");			continue;		}		if (strncasecmp(key, "CARDINFO{", 9) == 0) {			attr = get_key_attribute(space, key + 8, string, sizeof(string));			if (attr == NULL) {				Perror(space, "error parsing CARDINFO attribute");				goto invalid;			}			if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				dbg("cardinfo: '%s' '%s'", value, attr);				temp = (char *)cardinfo_get(space, attr);				if (!do_match(key, op, value, temp))					break;			} else {				Perror(space, "invalid CARDINFO{} operation");				goto invalid;			}			continue;		}		if (strncasecmp(key, "ATTR{", 5) == 0) {			attr = get_key_attribute(space, key + 4, string, sizeof(string));			if (attr == NULL) {				Perror(space, "error parsing ATTR attribute");				goto invalid;			}			if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				pair = value_find(space, "sysfs_device");				if (pair == NULL)					break;				dbg("sysfs_attr: '%s' '%s'", pair->value, attr);				temp = sysfs_attr_get_value(pair->value, attr);				if (!do_match(key, op, value, temp))					break;			} else {				Perror(space, "invalid ATTR{} operation");				goto invalid;			}			continue;		}		if (strncasecmp(key, "ENV{", 4) == 0) {			attr = get_key_attribute(space, key + 3, string, sizeof(string));			if (attr == NULL) {				Perror(space, "error parsing ENV attribute");				goto invalid;			}			if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				temp = getenv(attr);				dbg("env: '%s' '%s'", attr, temp);				if (!do_match(key, op, value, temp))					break;			} else if (op == KEY_OP_ASSIGN ||				   op == KEY_OP_ASSIGN_FINAL) {				strlcpy(result, value, sizeof(result));				apply_format(space, result, sizeof(result));				dbg("env set: '%s' '%s'", attr, result);				if (setenv(attr, result, op == KEY_OP_ASSIGN_FINAL))					break;			} else {				Perror(space, "invalid ENV{} operation");				goto invalid;			}			continue;		}		if (strcasecmp(key, "GOTO") == 0) {			if (op != KEY_OP_ASSIGN) {				Perror(space, "invalid GOTO operation");				goto invalid;			}			space->go_to = strdup(value);			if (space->go_to == NULL) {				err = -ENOMEM;				break;			}			continue;		}		if (strcasecmp(key, "INCLUDE") == 0) {			char *rootdir, *go_to;			const char *filename;			struct dirent *dirent;			DIR *dir;			int linenum;			if (op != KEY_OP_ASSIGN) {				Perror(space, "invalid INCLUDE operation");				goto invalid;			}			if (value[0] == '/')				strlcpy(string, value, sizeof(string));			else {				strlcpy(string, space->rootdir, sizeof(string));				strlcat(string, "/", sizeof(string));				strlcat(string, value, sizeof(string));			}			rootdir = space->rootdir;			go_to = space->go_to;			filename = space->filename;			linenum = space->linenum;			dir = opendir(string);			if (dir) {				count = strlen(string);				while ((dirent = readdir(dir)) != NULL) {					if (strcmp(dirent->d_name, ".") == 0 ||					    strcmp(dirent->d_name, "..") == 0)						continue;					string[count] = '\0';					strlcat(string, "/", sizeof(string));					strlcat(string, dirent->d_name, sizeof(string));					space->go_to = NULL;					space->rootdir = new_root_dir(string);					if (space->rootdir) {						err = parse(space, string);						free(space->rootdir);					} else						err = -ENOMEM;					if (space->go_to) {						Perror(space, "unterminated GOTO '%s'", space->go_to);						free(space->go_to);					}					if (err)						break;				}				closedir(dir);			} else {				space->go_to = NULL;				space->rootdir = new_root_dir(string);				if (space->rootdir) {					err = parse(space, string);					free(space->rootdir);				} else					err = -ENOMEM;				if (space->go_to) {					Perror(space, "unterminated GOTO '%s'", space->go_to);					free(space->go_to);				}			}			space->go_to = go_to;			space->rootdir = rootdir;			space->filename = filename;			space->linenum = linenum;			if (space->quit)				break;			if (err)				break;			continue;		}		if (strncasecmp(key, "ACCESS", 6) == 0) {			if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				if (value[0] != '/') {					strlcpy(string, space->rootdir, sizeof(string));					strlcat(string, "/", sizeof(string));					strlcat(string, value, sizeof(string));				} else {					strlcat(string, value, sizeof(string));				}				count = access(string, F_OK);				dbg("access(%s) = %i", value, count);				if (op == KEY_OP_MATCH && count != 0)					break;				if (op == KEY_OP_NOMATCH && count == 0)					break;			} else {				Perror(space, "invalid ACCESS operation");				goto invalid;			}			continue;		}		if (strncasecmp(key, "PRINT", 5) == 0) {			if (op != KEY_OP_ASSIGN) {				Perror(space, "invalid PRINT operation");				goto invalid;			}			strlcpy(string, value, sizeof(string));			apply_format(space, string, sizeof(string));			fwrite(string, strlen(string), 1, stdout);			continue;		}		if (strncasecmp(key, "ERROR", 5) == 0) {			if (op != KEY_OP_ASSIGN) {				Perror(space, "invalid ERROR operation");				goto invalid;			}			strlcpy(string, value, sizeof(string));			apply_format(space, string, sizeof(string));			fwrite(string, strlen(string), 1, stderr);			continue;		}		if (strncasecmp(key, "EXIT", 4) == 0) {			if (op != KEY_OP_ASSIGN) {				Perror(space, "invalid EXIT operation");				goto invalid;			}			strlcpy(string, value, sizeof(string));			apply_format(space, string, sizeof(string));			if (strcmp(string, "return") == 0)				return -EJUSTRETURN;			space->exit_code = strtol(string, NULL, 0);			space->quit = 1;			break;		}		if (strncasecmp(key, "CONFIG{", 7) == 0) {			attr = get_key_attribute(space, key + 6, string, sizeof(string));			if (attr == NULL) {				Perror(space, "error parsing CONFIG attribute");				goto invalid;			}			strlcpy(result, value, sizeof(result));			apply_format(space, result, sizeof(result));			if (op == KEY_OP_ASSIGN) {				err = value_set(space, attr, result);				dbg("CONFIG{%s}='%s'", attr, result);				break;			} else if (op == KEY_OP_MATCH || op == KEY_OP_NOMATCH) {				pair = value_find(space, attr);				if (pair == NULL)					break;				if (!do_match(key, op, result, pair->value))					break;			} else {				Perror(space, "invalid CONFIG{} operation");				goto invalid;			}		}		Perror(space, "unknown key '%s'", key);	}	return err;invalid:	Perror(space, "invalid rule");	return -EINVAL;}static int parse(struct space *space, const char *filename){	char *buf, *bufline, *line;	size_t bufsize, pos, count, linesize;	unsigned int linenum, i, j, linenum_adj;	int err;	dbg("start of file '%s'", filename);	if (file_map(filename, &buf, &bufsize) != 0) {		err = errno;		error("Unable to open file '%s': %s", filename, strerror(err));		return -err;	}	err = 0;		pos = 0;	linenum = 0;	linesize = 128;	line = malloc(linesize);	if (line == NULL)		return -ENOMEM;	space->filename = filename;	while (!err && pos < bufsize && !space->quit) {		count = line_width(buf, bufsize, pos);		bufline = buf + pos;		pos += count + 1;		linenum++;				/* skip whitespaces */		while (count > 0 && isspace(bufline[0])) {			bufline++;			count--;		}		if (count == 0)			continue;					/* comment check */		if (bufline[0] == '#')			continue;				if (count > linesize - 1) {			free(line);			linesize = (count + 127 + 1) & ~127;			if (linesize > 2048) {				error("file %s, line %i too long", filename, linenum);				err = -EINVAL;				break;			}			line = malloc(linesize);			if (line == NULL) {				err = -EINVAL;				break;			}		}				/* skip backslash and newline from multiline rules */		linenum_adj = 0;		for (i = j = 0; i < count; i++) {			if (bufline[i] == '\\' && bufline[i+1] == '\n') {				linenum_adj++;				continue;			}			line[j++] = bufline[i];		}		line[j] = '\0';		dbg("read (%i) '%s'", linenum, line);		space->linenum = linenum;		err = parse_line(space, line, linesize);		if (err == -EJUSTRETURN) {			err = 0;			break;		}		linenum += linenum_adj;	}	free(line);	space->filename = NULL;	space->linenum = -1;	file_unmap(buf, bufsize);	dbg("end of file '%s'", filename);	return err ? err : -abs(space->exit_code);}int init(const char *filename, const char *cardname){	struct space *space;	int err = 0, card, first;		sysfs_init();	if (!cardname) {		first = 1;		card = -1;		while (1) {			if (snd_card_next(&card) < 0)				break;			if (card < 0) {				if (first) {					error("No soundcards found...");					return -ENODEV;				}				break;			}			first = 0;			err = init_space(&space, card);			if (err == 0 &&			    (space->rootdir = new_root_dir(filename)) != NULL)				err = parse(space, filename);			free_space(space);			if (err < 0)				break;		}	} else {		card = snd_card_get_index(cardname);		if (card < 0) {			error("Cannot find soundcard '%s'...", cardname);			goto error;		}		memset(&space, 0, sizeof(space));		err = init_space(&space, card);		if (err == 0 &&		    (space->rootdir = new_root_dir(filename)) != NULL)			err = parse(space, filename);		free_space(space);	}  error:	sysfs_cleanup();	return err;}

⌨️ 快捷键说明

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