mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-10-29 05:40:25 -04:00 
			
		
		
		
	ucm: allow passing variables through ucm open string
It is useful to pass information like application capabilities
to the UCM configuration parser. Those variables are prefixed
with '@' for the configuration files.
An example:
   "<<<v1='a b c',x=12>>>hw:1"
Variables can substituted in the configuration:
   "${var:@v1}" -> "a b c"
   "${var:@x}" -> 12
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
			
			
This commit is contained in:
		
							parent
							
								
									46e991c9ce
								
							
						
					
					
						commit
						11ec9e497e
					
				
					 2 changed files with 63 additions and 0 deletions
				
			
		|  | @ -1356,6 +1356,57 @@ static int set_device(snd_use_case_mgr_t *uc_mgr, | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Parse open arguments | ||||||
|  |  * \param uc_mgr Use case manager | ||||||
|  |  * \param name name of card to open | ||||||
|  |  * \return the rest of the card name to open | ||||||
|  |  */ | ||||||
|  | const char *parse_open_variables(snd_use_case_mgr_t *uc_mgr, const char *name) | ||||||
|  | { | ||||||
|  | 	const char *end, *id; | ||||||
|  | 	char *args, *var; | ||||||
|  | 	snd_config_t *cfg, *n; | ||||||
|  | 	snd_config_iterator_t i, next; | ||||||
|  | 	char vname[128]; | ||||||
|  | 	size_t l; | ||||||
|  | 	int err; | ||||||
|  | 
 | ||||||
|  | 	end = strstr(name, ">>>"); | ||||||
|  | 	if (end == NULL) | ||||||
|  | 		return name; | ||||||
|  | 	l = end - name - 3; | ||||||
|  | 	args = alloca(l + 1); | ||||||
|  | 	strncpy(args, name + 3, l); | ||||||
|  | 	args[l] = '\0'; | ||||||
|  | 
 | ||||||
|  | 	err = snd_config_load_string(&cfg, args, 0); | ||||||
|  | 	if (err < 0) { | ||||||
|  | 		uc_error("error: open arguments are not valid (%s)", args); | ||||||
|  | 		goto skip; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* set arguments */ | ||||||
|  | 	snd_config_for_each(i, next, cfg) { | ||||||
|  | 		n = snd_config_iterator_entry(i); | ||||||
|  | 		err = snd_config_get_id(n, &id); | ||||||
|  | 		if (err < 0) | ||||||
|  | 			goto skip; | ||||||
|  | 		err = snd_config_get_ascii(n, &var); | ||||||
|  | 		if (err < 0) | ||||||
|  | 			goto skip; | ||||||
|  | 		snprintf(vname, sizeof(vname), "@%s", id); | ||||||
|  | 		err = uc_mgr_set_variable(uc_mgr, vname, var); | ||||||
|  | 		free(var); | ||||||
|  | 		if (err < 0) | ||||||
|  | 			goto skip; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	snd_config_delete(cfg); | ||||||
|  | skip: | ||||||
|  | 	return end + 3; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * \brief Init sound card use case manager. |  * \brief Init sound card use case manager. | ||||||
|  * \param uc_mgr Returned use case manager pointer |  * \param uc_mgr Returned use case manager pointer | ||||||
|  | @ -1388,6 +1439,9 @@ int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, | ||||||
| 		mgr->suppress_nodev_errors = 1; | 		mgr->suppress_nodev_errors = 1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (card_name[0] == '<' && card_name[1] == '<' && card_name[2] == '<') | ||||||
|  | 		card_name = parse_open_variables(mgr, card_name); | ||||||
|  | 
 | ||||||
| 	err = uc_mgr_card_open(mgr); | 	err = uc_mgr_card_open(mgr); | ||||||
| 	if (err < 0) { | 	if (err < 0) { | ||||||
| 		uc_mgr_free(mgr); | 		uc_mgr_free(mgr); | ||||||
|  |  | ||||||
|  | @ -278,6 +278,10 @@ static int evaluate_regex(snd_use_case_mgr_t *uc_mgr, | ||||||
| 		err = snd_config_get_id(n, &id); | 		err = snd_config_get_id(n, &id); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
| 			return err; | 			return err; | ||||||
|  | 		if (id[0] == '@') { | ||||||
|  | 			uc_error("error: value names starting with '@' are reserved for application variables"); | ||||||
|  | 			return -EINVAL; | ||||||
|  | 		} | ||||||
| 		err = uc_mgr_define_regex(uc_mgr, id, n); | 		err = uc_mgr_define_regex(uc_mgr, id, n); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
| 			return err; | 			return err; | ||||||
|  | @ -327,6 +331,11 @@ static int evaluate_define(snd_use_case_mgr_t *uc_mgr, | ||||||
| 		free(var); | 		free(var); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
| 			return err; | 			return err; | ||||||
|  | 		if (id[0] == '@') { | ||||||
|  | 			free(s); | ||||||
|  | 			uc_error("error: value names starting with '@' are reserved for application variables"); | ||||||
|  | 			return -EINVAL; | ||||||
|  | 		} | ||||||
| 		err = uc_mgr_set_variable(uc_mgr, id, s); | 		err = uc_mgr_set_variable(uc_mgr, id, s); | ||||||
| 		free(s); | 		free(s); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jaroslav Kysela
						Jaroslav Kysela