All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Kaskinen Tanu <tanu.kaskinen@digia.com>
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH] ucm: Allow cset commands to have values with spaces.
Date: Thu, 09 Aug 2012 17:12:53 +0200	[thread overview]
Message-ID: <s5hboik14lm.wl%tiwai@suse.de> (raw)
In-Reply-To: <1344523452.4283.43.camel@IT-D-4QB9Z4J>

At Thu, 9 Aug 2012 17:44:12 +0300,
Kaskinen Tanu wrote:
> 
> On Thu, 2012-08-09 at 16:07 +0200, Takashi Iwai wrote:
> > At Thu, 9 Aug 2012 16:43:31 +0300,
> > Tanu Kaskinen wrote:
> > > @@ -170,8 +170,23 @@ static int execute_cset(snd_ctl_t *ctl, char *cset)
> > >  	snd_ctl_elem_value_malloc(&value);
> > >  	snd_ctl_elem_info_malloc(&info);
> > >  
> > > -	pos = strrchr(cset, ' ');
> > > -	if (pos == NULL) {
> > > +	/* Find the space after the element id, taking quoting with
> > > +	   single-quotes into account. */
> > > +	for (pos = cset; *pos != '\0'; pos += strcspn(pos, "' ")) {
> > > +		if (*pos == ' ')
> > > +			break;
> > > +		if (*pos == '\'') {
> > 
> > A double-quote can be supported easily here...
> 
> True, I'll post v2 soon.

On the second thought, parsing the string intensively at that point
doesn't make sense.  The string will be parsed anyway in
snd_ctl_ascii_elem_id_parse(), then why not just let it give the next
pointer from there?

Below is a quick hack (untested at all!).  Could you check whether it
works?


Takashi

---
diff --git a/src/control/ctlparse.c b/src/control/ctlparse.c
index a16f96a..b0c4ef3 100644
--- a/src/control/ctlparse.c
+++ b/src/control/ctlparse.c
@@ -143,21 +143,19 @@ char *snd_ctl_ascii_elem_id_get(snd_ctl_elem_id_t *id)
 	return strdup(buf);
 }
 
-/**
- * \brief parse ASCII string as CTL element identifier
- * \param dst destination CTL identifier
- * \param str source ASCII string
- * \return zero on success, otherwise a negative error code
- */
-int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str)
+#ifndef DOC_HIDDEN
+/* used by UCM parser, too */
+int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str,
+				  const char **ret_ptr)
 {
 	int c, size, numid;
+	int err = -EINVAL;
 	char *ptr;
 
-	while (*str == ' ' || *str == '\t')
+	while (isspace(*str))
 		str++;
 	if (!(*str))
-		return -EINVAL;
+		goto out;
 	snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_MIXER);	/* default */
 	while (*str) {
 		if (!strncasecmp(str, "numid=", 6)) {
@@ -165,7 +163,7 @@ int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str)
 			numid = atoi(str);
 			if (numid <= 0) {
 				fprintf(stderr, "amixer: Invalid numid %d\n", numid);
-				return -EINVAL;
+				goto out;
 			}
 			snd_ctl_elem_id_set_numid(dst, atoi(str));
 			while (isdigit(*str))
@@ -191,7 +189,7 @@ int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str)
 				snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_SEQUENCER);
 				str += 9;
 			} else {
-				return -EINVAL;
+				goto out;
 			}
 		} else if (!strncasecmp(str, "name=", 5)) {
 			char buf[64];
@@ -239,11 +237,33 @@ int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str)
 		if (*str == ',') {
 			str++;
 		} else {
+			/* when ret_ptr is given, allow to terminate gracefully
+			 * at the next space letter
+			 */
+			if (ret_ptr && isspace(*str))
+				break;
 			if (*str)
-				return -EINVAL;
+				goto out;
 		}
 	}			
-	return 0;
+	err = 0;
+
+ out:
+	if (ret_ptr)
+		*ret_ptr = str;
+	return err;
+}
+#endif
+
+/**
+ * \brief parse ASCII string as CTL element identifier
+ * \param dst destination CTL identifier
+ * \param str source ASCII string
+ * \return zero on success, otherwise a negative error code
+ */
+int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str)
+{
+	return __snd_ctl_ascii_elem_id_parse(dst, str, NULL);
 }
 
 static int get_ctl_enum_item_index(snd_ctl_t *handle,
diff --git a/src/ucm/main.c b/src/ucm/main.c
index 4b37776..bd5c348 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -31,6 +31,7 @@
  */
 
 #include "ucm_local.h"
+#include <ctype.h>
 #include <stdarg.h>
 #include <pthread.h>
 
@@ -158,9 +159,13 @@ static int open_ctl(snd_use_case_mgr_t *uc_mgr,
 	return 0;
 }
 
+extern int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst,
+					 const char *str,
+					 const char **ret_ptr);
+
 static int execute_cset(snd_ctl_t *ctl, char *cset)
 {
-	char *pos;
+	const char *pos;
 	int err;
 	snd_ctl_elem_id_t *id;
 	snd_ctl_elem_value_t *value;
@@ -170,16 +175,16 @@ static int execute_cset(snd_ctl_t *ctl, char *cset)
 	snd_ctl_elem_value_malloc(&value);
 	snd_ctl_elem_info_malloc(&info);
 
-	pos = strrchr(cset, ' ');
-	if (pos == NULL) {
+	err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos);
+	if (err < 0)
+		goto __fail;
+	while (*pos && isspace(*pos))
+		pos++;
+	if (!*pos) {
 		uc_error("undefined value for cset >%s<", cset);
 		err = -EINVAL;
 		goto __fail;
 	}
-	*pos = '\0';
-	err = snd_ctl_ascii_elem_id_parse(id, cset);
-	if (err < 0)
-		goto __fail;
 	snd_ctl_elem_value_set_id(value, id);
 	snd_ctl_elem_info_set_id(info, id);
 	err = snd_ctl_elem_read(ctl, value);
@@ -188,7 +193,7 @@ static int execute_cset(snd_ctl_t *ctl, char *cset)
 	err = snd_ctl_elem_info(ctl, info);
 	if (err < 0)
 		goto __fail;
-	err = snd_ctl_ascii_value_parse(ctl, value, info, pos + 1);
+	err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
 	if (err < 0)
 		goto __fail;
 	err = snd_ctl_elem_write(ctl, value);
@@ -196,9 +201,6 @@ static int execute_cset(snd_ctl_t *ctl, char *cset)
 		goto __fail;
 	err = 0;
       __fail:
-	if (pos != NULL)
-		*pos = ' ';
-
 	if (id != NULL)
 		free(id);
 	if (value != NULL)

  reply	other threads:[~2012-08-09 14:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-09 13:43 [PATCH] ucm: Allow cset commands to have values with spaces Tanu Kaskinen
2012-08-09 14:07 ` Takashi Iwai
2012-08-09 14:44   ` Kaskinen Tanu
2012-08-09 15:12     ` Takashi Iwai [this message]
2012-08-09 15:23       ` Kaskinen Tanu
2012-08-09 15:16 ` [PATCH v2] " Tanu Kaskinen

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=s5hboik14lm.wl%tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=tanu.kaskinen@digia.com \
    /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.