alsactl init: Add CTL{do_search} and CTL{do_count} parsers

To increase configuration readability, add CTL{do_search} and CTL{do_count}
actions. The old PROGRAM=="__ctl_search" notion is also allowed.

Add CTL{write} to XML documentation.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2009-10-08 13:47:27 +02:00
parent 11b60426b3
commit a227f00690
4 changed files with 179 additions and 146 deletions

View file

@ -270,6 +270,24 @@
comma (,).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>do_search</option></term>
<listitem>
<para>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").</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>do_count</option></term>
<listitem>
<para>Search for a controls and return total count
of matched ones. The CTL{name} key might contain match
characters * and ?.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
@ -410,6 +428,15 @@
next key on line).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>CTL{write}</option></term>
<listitem>
<para>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).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ENV{<replaceable>key</replaceable>}</option></term>
@ -439,7 +466,8 @@
<varlistentry>
<term><option>GOTO</option></term>
<listitem>
<para>Jumps to the next LABEL with a matching name</para>
<para>Jumps to the next LABEL with a matching name.
The goto cannot jump backward.</para>
</listitem>
</varlistentry>

View file

@ -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"

View file

@ -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"

View file

@ -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;