All of lore.kernel.org
 help / color / mirror / Atom feed
From: libin.yang@linux.intel.com
To: perex@perex.cz, alsa-devel@alsa-project.org
Cc: libin.yang@intel.com
Subject: [alsa-devel] [alsa-lib][RFC PATCH] ucm: reset config id of condition items
Date: Thu, 23 Apr 2020 09:58:55 +0800	[thread overview]
Message-ID: <1587607135-20106-1-git-send-email-libin.yang@linux.intel.com> (raw)

From: Libin Yang <libin.yang@intel.com>

UCMv2 supports "If" statement and will merge the same items with
compound_merge(). If the items have the same id, it will fail to
add the config items. And the id of the item in an array is
automatically generated with the increased number. It is probably
that some items to be merged have the same id. Let's add prefix
in the id to avoid such situation.

For example:

If.seq1 {
	Condition {
		Type ControlExists
		Control "name='PGA1.0 1 Master Playback Volume'"
	}
	True {
		EnableSequence [
			cset "name='PGA1.0 1 Master Playback Volume' 50"
		]
	}
}

If.seq2 {
	Condition {
		Type ControlExists
		Control "name='PGA2.0 2 Master Playback Volume'"
	}
	True {
		EnableSequence [
			cset "name='PGA2.0 2 Master Playback Volume' 50"
		]
	}
}

If.seq3 {
	Condition {
		Type ControlExists
		Control "name='PGA3.0 3 Master Playback Volume'"
	}
	True {
		EnableSequence [
			cset "name='PGA3.0 3 Master Playback Volume' 50"
		]
	}
}

If seq1, seq2 and seq3 conditions are true, UCM will fail to initialize.

This patch rename the config id to avoid the same id conflict.

Signed-off-by: Libin Yang <libin.yang@intel.com>
---
 include/conf.h     |  2 +-
 src/conf.c         | 21 +++++++++++++++++++++
 src/ucm/ucm_cond.c | 28 ++++++++++++++++++++++++----
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/include/conf.h b/include/conf.h
index 456b272..adb3d84 100644
--- a/include/conf.h
+++ b/include/conf.h
@@ -139,7 +139,7 @@ int snd_config_imake_safe_string(snd_config_t **config, const char *key, const c
 int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr);
 
 snd_config_type_t snd_config_get_type(const snd_config_t *config);
-
+int snd_config_of_array(const snd_config_t *config);
 int snd_config_set_id(snd_config_t *config, const char *id);
 int snd_config_set_integer(snd_config_t *config, long value);
 int snd_config_set_integer64(snd_config_t *config, long long value);
diff --git a/src/conf.c b/src/conf.c
index 50d0403..43d565b 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -435,6 +435,8 @@ struct _snd_config {
 	char *id;
 	snd_config_type_t type;
 	int refcount; /* default = 0 */
+	/* member of an array */
+	int of_array;
 	union {
 		long integer;
 		long long integer64;
@@ -1123,6 +1125,7 @@ static int _snd_config_make(snd_config_t **config, char **id, snd_config_type_t
 		*id = NULL;
 	}
 	n->type = type;
+	n->of_array = 0;
 	if (type == SND_CONFIG_TYPE_COMPOUND)
 		INIT_LIST_HEAD(&n->u.compound.fields);
 	*config = n;
@@ -1316,6 +1319,8 @@ static int parse_array_def(snd_config_t *parent, input_t *input, int *idx, int s
 	default:
 		unget_char(c, input);
 		err = parse_value(&n, parent, input, &id, skip);
+		/* this is a member of an array */
+		n->of_array = 1;
 		if (err < 0)
 			goto __end;
 		break;
@@ -1784,6 +1789,22 @@ snd_config_type_t snd_config_get_type(const snd_config_t *config)
 }
 
 /**
+ * \brief Returns the of_array of a configuration node.
+ * \param config Handle to the configuration node.
+ * \return of_array of the node
+ *
+ * The returned value indicates whether the node is a member of an array.
+ *
+ * \par Conforming to:
+ * LSB 3.2
+ */
+int snd_config_of_array(const snd_config_t *config)
+{
+	assert(config);
+	return config->of_array;
+}
+
+/**
  * \brief Returns the id of a configuration node.
  * \param[in] config Handle to the configuration node.
  * \param[out] id The function puts the pointer to the id string at the
diff --git a/src/ucm/ucm_cond.c b/src/ucm/ucm_cond.c
index 22b418d..725a69e 100644
--- a/src/ucm/ucm_cond.c
+++ b/src/ucm/ucm_cond.c
@@ -347,14 +347,15 @@ static void config_dump(snd_config_t *cfg)
 }
 #endif
 
-static int compound_merge(const char *id,
+static int compound_merge(const char *id, const char *cname,
 			  snd_config_t *dst, snd_config_t *src,
 			  snd_config_t *before, snd_config_t *after)
 {
 	snd_config_iterator_t i, next;
 	snd_config_t *n, *_before = NULL, *_after = NULL;
 	const char *s;
-	int err;
+	char s1[32];
+	int err, cnt;
 
 	if (snd_config_get_type(src) != SND_CONFIG_TYPE_COMPOUND) {
 		uc_error("compound type expected for If True/False block");
@@ -387,8 +388,22 @@ static int compound_merge(const char *id,
 		return -EINVAL;
 	}
 
+	cnt = 0;
 	snd_config_for_each(i, next, src) {
 		n = snd_config_iterator_entry(i);
+		/*
+		 * If n is an array member, n->id is automatically generated.
+		 * It is prossible that n->id is used by other array member,
+		 * which will be merged with this one. So let's add prefix
+		 * to the id to avoid the conflict.
+		 */
+		if (snd_config_of_array(n)) {
+			err = snd_config_get_id(n, &s);
+			if (err < 0)
+				return err; /* FIXME: this will never happen */
+			snprintf(s1, sizeof(s1), "%s-%d-%s", cname, cnt++, s);
+			snd_config_set_id(n, (const char *)s1);
+		}
 		err = snd_config_remove(n);
 		if (err < 0)
 			return err;
@@ -422,7 +437,7 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
 {
 	snd_config_iterator_t i, i2, next, next2;
 	snd_config_t *a, *n, *n2, *parent2, *before, *after;
-	const char *id;
+	const char *id, *cname;
 	int err;
 
 	if (uc_mgr->conf_format < 2) {
@@ -437,6 +452,10 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
 
 	snd_config_for_each(i, next, cond) {
 		n = snd_config_iterator_entry(i);
+		err = snd_config_get_id(n, &cname);
+		if (err < 0)
+			return err; /* FIXME: this will never happen */
+
 		before = after = NULL;
 		err = if_eval_one(uc_mgr, n, &a, &before, &after);
 		if (err < 0)
@@ -469,7 +488,8 @@ __add:
 				err = snd_config_search(parent, id, &parent2);
 				if (err == -ENOENT)
 					goto __add;
-				err = compound_merge(id, parent2, n2, before, after);
+				err = compound_merge(id, cname, parent2, n2,
+						     before, after);
 				if (err < 0)
 					return err;
 			}
-- 
2.7.4


             reply	other threads:[~2020-04-23  2:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-23  1:58 libin.yang [this message]
2020-04-23 13:06 ` [alsa-devel] [alsa-lib][RFC PATCH] ucm: reset config id of condition items Pierre-Louis Bossart
2020-04-23 17:36   ` Jaroslav Kysela
2020-04-23 18:27     ` Pierre-Louis Bossart
2020-04-24  3:22     ` Yang, Libin
2020-04-29 13:47       ` Jaroslav Kysela
2020-05-01 13:44         ` Yang, Libin
2020-05-08 10:47           ` Jaroslav Kysela
2020-05-09  8:43             ` Yang, Libin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1587607135-20106-1-git-send-email-libin.yang@linux.intel.com \
    --to=libin.yang@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=libin.yang@intel.com \
    --cc=perex@perex.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.