diff --git a/alsactl/alsactl_init.xml b/alsactl/alsactl_init.xml
index dd4239c..eefe9ef 100644
--- a/alsactl/alsactl_init.xml
+++ b/alsactl/alsactl_init.xml
@@ -270,6 +270,24 @@
comma (,).
+
+
+
+ Search for a control. Value "1" is returned
+ if a control was found. The CTL{name} key might
+ contain match characters * and ?. An control index
+ might be specified as first argument starting from
+ zero (e.g. CTL{do_search 2}="1").
+
+
+
+
+
+ Search for a controls and return total count
+ of matched ones. The CTL{name} key might contain match
+ characters * and ?.
+
+
@@ -410,6 +428,15 @@
next key on line).
+
+
+
+ Value is set (written) also to soundcard's control
+ device (all control values are set to specified value).
+ The result of set operation is true when operation
+ succeed (it means continue with next key on line).
+
+
@@ -439,7 +466,8 @@
- Jumps to the next LABEL with a matching name
+ Jumps to the next LABEL with a matching name.
+ The goto cannot jump backward.
diff --git a/alsactl/init/default b/alsactl/init/default
index dbe30ac..55fb48f 100644
--- a/alsactl/init/default
+++ b/alsactl/init/default
@@ -17,22 +17,22 @@ ENV{cvolume}:="12dB"
ENV{has_pmaster_vol}:="false"
CTL{reset}="mixer"
-CTL{name}="Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Playback Volume",CTL{do_search}=="1", \
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
-CTL{name}="Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Master Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Master Playback Volume",CTL{do_search}=="1", \
ENV{has_pmaster_vol}:="true", \
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
-CTL{name}="Master Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Master Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Master Digital Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Master Digital Playback Volume",CTL{do_search}=="1", \
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
-CTL{name}="Master Digital Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Master Digital Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
@@ -42,7 +42,7 @@ ENV{has_pmaster_vol}=="true",CTL{write}=="0dB",GOTO=""
ENV{has_pmaster_vol}=="true",CTL{write}=="100%",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
LABEL=""
-CTL{name}="Front Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Front Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
@@ -52,7 +52,7 @@ ENV{has_pmaster_vol}=="true",CTL{write}=="0dB",GOTO=""
ENV{has_pmaster_vol}=="true",CTL{write}=="100%",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
LABEL=""
-CTL{name}="Headphone Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Headphone Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
@@ -63,7 +63,7 @@ ENV{has_pmaster_vol}=="true",CTL{write}=="0dB",GOTO=""
ENV{has_pmaster_vol}=="true",CTL{write}=="100%",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
LABEL=""
-CTL{name}="Headphone Playback Switch",CTL{index}="1",PROGRAM=="__ctl_search", \
+CTL{name}="Headphone Playback Switch",CTL{index}="1",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
@@ -73,13 +73,13 @@ ENV{has_pmaster_vol}=="true",CTL{write}=="0dB",GOTO=""
ENV{has_pmaster_vol}=="true",CTL{write}=="100%",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
LABEL=""
-CTL{name}="Speaker Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Speaker Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="PC Speaker Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="PC Speaker Playback Volume",CTL{do_search}=="1", \
CTL{values}="$env{pvolume}",RESULT!="0",CTL{values}="$env{ppercent}"
-CTL{name}="PC Speaker Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="PC Speaker Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
@@ -93,8 +93,8 @@ CTL{dBmin}=="-34.50dB",CTL{dBmax}=="12.00dB",CTL{write}=="0dB",GOTO=""
CTL{dBmin}=="-30.00dB",CTL{dBmax}=="0dB",CTL{write}=="0dB",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="75%"
LABEL=""
-CTL{name}="PCM Playback Switch",PROGRAM=="__ctl_search", CTL{values}="on"
-CTL{name}="PCM Switch",PROGRAM=="__ctl_search",CTL{values}="on"
+CTL{name}="PCM Playback Switch",CTL{do_search}=="1", CTL{values}="on"
+CTL{name}="PCM Switch",CTL{do_search}=="1",CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="PCM Playback Volume",CTL{index}="1",PROGRAM!="__ctl_search", \
@@ -107,33 +107,33 @@ CTL{dBmin}=="-34.50dB",CTL{dBmax}=="12.00dB",CTL{write}=="0dB",GOTO=""
CTL{dBmin}=="-30.00dB",CTL{dBmax}=="0dB",CTL{write}=="0dB",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="75%"
LABEL=""
-CTL{name}="PCM Playback Switch",CTL{index}="1",PROGRAM=="__ctl_search", \
+CTL{name}="PCM Playback Switch",CTL{index}="1",CTL{do_search}=="1", \
CTL{values}="on"
-CTL{name}="PCM Switch",CTL{index}="1",PROGRAM=="__ctl_search", \
+CTL{name}="PCM Switch",CTL{index}="1",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="DAC Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="DAC Playback Volume",CTL{do_search}=="1", \
CTL{values}="$env{pvolume}",RESULT!="0",CTL{values}="$env{ppercent}"
-CTL{name}="DAC Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="DAC Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Synth Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Synth Playback Volume",CTL{do_search}=="1", \
CTL{values}="$env{pvolume}",RESULT!="0",CTL{values}="$env{ppercent}"
-CTL{name}="Synth Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Synth Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Wave Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Wave Playback Volume",CTL{do_search}=="1", \
CTL{values}="100%"
-CTL{name}="Wave Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Wave Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Music Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Music Playback Volume",CTL{do_search}=="1", \
CTL{values}="100%"
-CTL{name}="Music Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Music Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
@@ -146,25 +146,25 @@ CTL{dBmin}=="-34.50dB",CTL{dBmax}=="12.00dB",CTL{write}=="0dB",GOTO=""
CTL{dBmin}=="-30.00dB",CTL{dBmax}=="0dB",CTL{write}=="0dB",GOTO=""
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
LABEL=""
-CTL{name}="CD Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="CD Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Mono Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Mono Playback Volume",CTL{do_search}=="1", \
CTL{values}="$env{pvolume}",RESULT!="0",CTL{values}="$env{ppercent}"
-CTL{name}="Mono Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Mono Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="Master Mono Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Master Mono Playback Volume",CTL{do_search}=="1", \
CTL{values}="$env{pvolume}",RESULT!="0",CTL{values}="$env{ppercent}"
-CTL{name}="Master Mono Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Master Mono Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
-CTL{name}="AC97 Playback Volume",PROGRAM=="__ctl_search", \
+CTL{name}="AC97 Playback Volume",CTL{do_search}=="1", \
CTL{values}="100%"
-CTL{name}="AC97 Playback Switch",PROGRAM=="__ctl_search", \
+CTL{name}="AC97 Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
#
@@ -172,7 +172,7 @@ CTL{name}="AC97 Playback Switch",PROGRAM=="__ctl_search", \
#
CTL{reset}="mixer"
-CTL{name}="DRC Range",PROGRAM=="__ctl_search", \
+CTL{name}="DRC Range",CTL{do_search}=="1", \
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
# **************************************************************************
@@ -180,9 +180,9 @@ CTL{name}="DRC Range",PROGRAM=="__ctl_search", \
# **************************************************************************
CTL{reset}="mixer"
-CTL{name}="Capture Volume",PROGRAM=="__ctl_search", \
+CTL{name}="Capture Volume",CTL{do_search}=="1", \
CTL{write}!="$env{cvolume}",CTL{values}="$env{cpercent}"
-CTL{name}="Capture Switch",PROGRAM=="__ctl_search", \
+CTL{name}="Capture Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{name}="Input Source",PROGRAM!="__ctl_search", GOTO=""
@@ -191,5 +191,5 @@ CTL{enums}=="*|Internal Mic|*",CTL{values}="Internal Mic", \
CTL{enums}=="*|Mic|*",CTL{values}="Mic"
LABEL=""
-CTL{name}="Internal Mic Boost",PROGRAM=="__ctl_search", \
+CTL{name}="Internal Mic Boost",CTL{do_search}=="1", \
CTL{values}="on"
diff --git a/alsactl/init/test b/alsactl/init/test
index 26db2a3..56659f8 100644
--- a/alsactl/init/test
+++ b/alsactl/init/test
@@ -37,9 +37,9 @@ PRINT=" CTL{index}=\"$ctl{index}\"\n"
ERROR="Ignore following error:\n "
PROGRAM="__just_test"
-PRINT="__ctl_count test:\n"
-CTL{search}="mixer", CTL{name}="*Switch*", PROGRAM="__ctl_count", \
- PRINT=" *Switch* count result: $result\n"
+PRINT="CTL{do_count} test:\n"
+CTL{search}="mixer", CTL{name}="*Switch*", \
+ PRINT=" *Switch* count result: $ctl{do_count}\n"
PRINT="__ctl_search test:\n"
CTL{search}="mixer", CTL{name}="*Switch*", PROGRAM!="__ctl_search", GOTO="skip_switch_search"
@@ -60,7 +60,7 @@ PRINT=" CTL{name}=\"$ctl{name}\"\n"
PRINT=" CTL{index}=\"$ctl{index}\"\n"
PRINT="First ten elements:\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 0", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 0}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #0:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -79,7 +79,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 1", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 1}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #1:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -98,7 +98,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 2", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 2}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #2:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -117,7 +117,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 3", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 3}!="3", GOTO="skip_first_ten_search"
PRINT=" Element #3:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -136,7 +136,7 @@ PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{step}=\"$ctl{step}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 4", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 4}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #4:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -155,7 +155,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 5", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 5}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #5:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -174,7 +174,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 6", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 6}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #6:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -193,7 +193,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 7", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 7}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #7:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -212,7 +212,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 8", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 8}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #8:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -231,7 +231,7 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
-CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 9", GOTO="skip_first_ten_search"
+CTL{search}="mixer", CTL{name}="*", CTL{do_search 9}!="1", GOTO="skip_first_ten_search"
PRINT=" Element #9:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
PRINT=" CTL{iface}=\"$ctl{iface}\"\n"
@@ -254,15 +254,15 @@ LABEL="skip_first_ten_search"
PRINT="Elements write test #1:\n", \
CTL{search}="mixer", CTL{name}="Front Playback Switch", \
- PROGRAM="__ctl_search", CTL{value}="on,on", \
+ CTL{do_search}=="1", CTL{value}="on,on", \
PRINT=" result=$result\n"
PRINT="Elements write test #2:\n", \
CTL{search}="mixer", CTL{name}="Front Playback Volume", \
- PROGRAM="__ctl_search", CTL{value}="32,32", \
+ CTL{do_search}=="1", CTL{value}="32,32", \
PRINT=" result=$result\n"
PRINT="Elements write test #3:\n", \
CTL{search}="mixer", CTL{name}="Front Playback Volume Error", \
- PROGRAM="__ctl_search"
+ CTL{do_search}=="1", \
PRINT=" result=$result\n"
#CTL{reset}="mixer", CTL{name}="Input Source", PRINT="***$ctl{enums}\n"
diff --git a/alsactl/init_parse.c b/alsactl/init_parse.c
index 83857a2..8d9c7ae 100644
--- a/alsactl/init_parse.c
+++ b/alsactl/init_parse.c
@@ -485,6 +485,46 @@ static int set_ctl_value(struct space *space, const char *value, int all)
return -EINVAL;
}
+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;
+}
+
+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;
+}
+
static const char *elemid_get(struct space *space, const char *attr)
{
long long val;
@@ -649,6 +689,56 @@ dbvalue:
}
return res;
}
+ if (strncasecmp(attr, "do_search", 9) == 0) {
+ int err, index = 0;
+ snd_hctl_elem_t *elem;
+ snd_ctl_elem_id_t *id;
+ char *pos = strchr(attr, ' ');
+ if (pos)
+ index = strtol(pos, NULL, 0);
+ err = snd_ctl_elem_id_malloc(&id);
+ if (err < 0)
+ return NULL;
+ 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;
+ }
+ strcpy(res, "1");
+ snd_ctl_elem_id_copy(space->ctl_id, id);
+ snd_ctl_elem_id_free(id);
+ dbg("do_ctl_search found a control");
+ return res;
+ next_search:
+ elem = snd_hctl_elem_next(elem);
+ }
+ snd_ctl_elem_id_free(id);
+ strcpy(res, "0");
+ return res;
+ }
+ if (strncasecmp(attr, "do_count", 8) == 0) {
+ int err, index = 0;
+ snd_hctl_elem_t *elem;
+ snd_ctl_elem_id_t *id;
+ err = snd_ctl_elem_id_malloc(&id);
+ if (err < 0)
+ return NULL;
+ elem = snd_hctl_first_elem(space->ctl_handle);
+ while (elem) {
+ snd_hctl_elem_get_id(elem, id);
+ if (ctl_match(space->ctl_id, id))
+ index++;
+ elem = snd_hctl_elem_next(elem);
+ }
+ snd_ctl_elem_id_free(id);
+ sprintf(res, "%u", index);
+ dbg("do_ctl_count found %s controls", res);
+ return res;
+ }
Perror(space, "unknown ctl{} attribute '%s'", attr);
return NULL;
value:
@@ -1150,108 +1240,23 @@ found:
*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;
-}
-
-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;
-}
-
static
int 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)
+ if (strncmp(command0, "__ctl_search", 12) == 0) {
+ const char *res = elemid_get(space, "do_search");
+ if (res == NULL || strcmp(res, "1") != 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;
+ return EXIT_SUCCESS;
}
- if (cmdlen == 11 && strncmp(command0, "__ctl_count", 11) == 0) {
- index = 0;
- err = snd_ctl_elem_id_malloc(&id);
- if (err < 0)
+ if (strncmp(command0, "__ctl_count", 11) == 0) {
+ const char *res = elemid_get(space, "do_count");
+ if (res == NULL || strcmp(res, "0") == 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) {
+ strlcpy(result, res, ressize);
+ return EXIT_SUCCESS;
}
Perror(space, "unknown buildin command '%s'", command0);
return EXIT_FAILURE;