static void yyerror(char *, ...);
static void build_soundcard(char *name);
-static void build_control_begin(int iface, unsigned int device, unsigned int subdevice, char *name, unsigned int index);
+static void build_control_begin(void);
static void build_control_end(void);
+static void set_control_iface(int iface);
+static void set_control_device(int dev);
+static void set_control_subdevice(int subdev);
+static void set_control_name(char *name);
+static void set_control_index(int idx);
+static void set_control_type(snd_control_type_t type);
static void set_control_boolean(int val);
static void set_control_integer(long val);
-static void set_control_bytearray(struct bytearray val);
/* local variables */
/* other keywords */
%token L_SOUNDCARD L_CONTROL L_RAWDATA
%token L_GLOBAL L_HWDEP L_MIXER L_PCM L_RAWMIDI L_TIMER L_SEQUENCER
-
+%token L_IDENT L_IFACE L_NAME L_DEVICE L_SUBDEVICE L_INDEX
+%token L_BOOL L_INT L_ENUM L_BYTE
%type <b_value> boolean
%type <i_value> integer iface
| soundcards soundcard
;
-soundcard : L_CONTROL '(' iface ',' integer ',' integer ',' string ',' integer
- { build_control_begin($3, $5, $7, $9, $11); }
- ',' controls ')' { build_control_end(); }
- | error { yyerror( "an unknown keyword in the soundcard{} level"); }
+soundcard : L_CONTROL '(' L_IDENT '=' { build_control_begin(); }
+ '{' ctlids '}' ',' controls ')' { build_control_end(); }
+ | error { yyerror("an unknown keyword in the soundcard{} level"); }
+ ;
+
+ctlids : ctlid
+ | ctlids ',' ctlid
+ ;
+
+ctlid : L_IFACE '=' iface { set_control_iface($3); }
+ | L_DEVICE '=' integer { set_control_device($3); }
+ | L_SUBDEVICE '=' integer { set_control_subdevice($3); }
+ | L_NAME '=' string { set_control_name($3); }
+ | L_INDEX '=' integer { set_control_index($3); }
+ | error { yyerror("an unknown keyword in the control ID level"); }
;
controls : control
- | controls ',' control
;
-control : boolean { set_control_boolean($1); }
- | integer { set_control_integer($1); }
- | rawdata { set_control_bytearray($1); }
+control : L_BOOL '=' { set_control_type(SND_CONTROL_TYPE_BOOLEAN); } '{' datas '}'
+ | L_INT '=' { set_control_type(SND_CONTROL_TYPE_INTEGER); } '{' datas '}'
+ | L_ENUM '=' { set_control_type(SND_CONTROL_TYPE_ENUMERATED); } '{' datas '}'
+ | L_BYTE '=' { set_control_type(SND_CONTROL_TYPE_BYTES); } '{' datas '}'
| error { yyerror( "an unknown keyword in the control() data parameter" ); }
;
+datas : data
+ | datas ',' data
+ ;
+
+data : boolean { set_control_boolean($1); }
+ | integer { set_control_integer($1); }
+ | error { yyerror( "an unknown keyword in the control() data argument" ); }
+ ;
+
iface : L_INTEGER { $$ = $1; }
| L_GLOBAL { $$ = SND_CONTROL_IFACE_CARD; }
| L_HWDEP { $$ = SND_CONTROL_IFACE_HWDEP; }
free(name);
}
-static void build_control_begin(int iface, unsigned int device, unsigned int subdevice, char *name, unsigned int index)
+static void build_control_begin(void)
{
struct ctl_control **first;
struct ctl_control *ctl;
first = &Xsoundcard->control.controls;
Xcontrol = (struct ctl_control *)malloc(sizeof(struct ctl_control));
if (!Xcontrol) {
- free(name);
error_nomem();
return;
}
} else {
*first = Xcontrol;
}
+}
+
+static void build_control_end(void)
+{
+ Xcontrol = NULL;
+}
+
+static void set_control_iface(int iface)
+{
Xcontrol->c.id.iface = iface;
- Xcontrol->c.id.device = device;
- Xcontrol->c.id.subdevice = subdevice;
+}
+
+static void set_control_device(int dev)
+{
+ Xcontrol->c.id.device = dev;
+}
+
+static void set_control_subdevice(int subdev)
+{
+ Xcontrol->c.id.subdevice = subdev;
+}
+
+static void set_control_name(char *name)
+{
+ if (name == NULL)
+ return;
strncpy(Xcontrol->c.id.name, name, sizeof(Xcontrol->c.id.name));
- Xcontrol->c.id.index = index;
free(name);
}
-static void build_control_end(void)
+static void set_control_index(int idx)
{
- Xcontrol = NULL;
+ Xcontrol->c.id.index = idx;
+}
+
+static void set_control_type(snd_control_type_t type)
+{
+ Xcontrol->type = Xtype = type;
}
static void set_control_boolean(int val)
{
+ if (Xposition >= 512)
+ yyerror("Array overflow.");
switch (Xtype) {
- case SND_CONTROL_TYPE_NONE:
case SND_CONTROL_TYPE_BOOLEAN:
- Xtype = Xcontrol->type = SND_CONTROL_TYPE_BOOLEAN;
+ Xcontrol->c.value.integer.value[Xposition++] = val ? 1 : 0;
break;
case SND_CONTROL_TYPE_INTEGER:
+ Xcontrol->c.value.integer.value[Xposition++] = val ? 1 : 0;
+ break;
+ case SND_CONTROL_TYPE_ENUMERATED:
+ Xcontrol->c.value.enumerated.item[Xposition++] = val ? 1 : 0;
break;
- default:
- yyerror("Unexpected previous type (%i).\n", Xtype);
+ case SND_CONTROL_TYPE_BYTES:
+ Xcontrol->c.value.bytes.data[Xposition++] = val ? 1 : 0;
+ break;
+ default: break;
}
- if (Xposition < 512)
- Xcontrol->c.value.integer.value[Xposition++] = val ? 1 : 0;
- else
- yyerror("Array overflow.");
}
static void set_control_integer(long val)
{
- unsigned int xx;
-
+ if (Xposition >= 512)
+ yyerror("Array overflow.");
switch (Xtype) {
- case SND_CONTROL_TYPE_NONE:
case SND_CONTROL_TYPE_BOOLEAN:
- case SND_CONTROL_TYPE_INTEGER:
- Xtype = Xcontrol->type = SND_CONTROL_TYPE_INTEGER;
+ Xcontrol->c.value.integer.value[Xposition++] = val ? 1 : 0;
break;
- default:
- yyerror("Unexpected previous type (%i).\n", Xtype);
- }
- if (Xposition < 512) {
- xx = val;
+ case SND_CONTROL_TYPE_INTEGER:
Xcontrol->c.value.integer.value[Xposition++] = val;
+ break;
+ case SND_CONTROL_TYPE_ENUMERATED:
+ Xcontrol->c.value.enumerated.item[Xposition++] = (unsigned int)val;
+ break;
+ case SND_CONTROL_TYPE_BYTES:
+ Xcontrol->c.value.bytes.data[Xposition++] = (unsigned char)val;
+ break;
+ default: break;
}
}
-
-static void set_control_bytearray(struct bytearray val)
-{
- if (Xtype != SND_CONTROL_TYPE_NONE && Xtype != SND_CONTROL_TYPE_BYTES)
- yyerror("Unexpected previous type (%i).\n", Xtype);
- Xtype = Xcontrol->type = SND_CONTROL_TYPE_BYTES;
-
- if (val.datalen + Xposition > 512)
- yyerror("Byte array too large for control.");
-
- memcpy(&Xcontrol->c.value.bytes.data[Xposition], val.data, val.datalen);
- Xposition += val.datalen;
-}
return 0;
switch (cctl->info.type) {
case SND_CONTROL_TYPE_BOOLEAN:
- if (uctl->type != SND_CONTROL_TYPE_BOOLEAN && uctl->type != SND_CONTROL_TYPE_INTEGER) {
+ if (uctl->type != SND_CONTROL_TYPE_BOOLEAN) {
error("A wrong type %i for the control '%s'. The type integer is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
}
break;
case SND_CONTROL_TYPE_INTEGER:
- if (uctl->type != SND_CONTROL_TYPE_BOOLEAN && uctl->type != SND_CONTROL_TYPE_INTEGER) {
+ if (uctl->type != SND_CONTROL_TYPE_INTEGER) {
error("A wrong type %i for the control '%s'. The type integer is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
}
break;
case SND_CONTROL_TYPE_ENUMERATED:
- if (uctl->type != SND_CONTROL_TYPE_BOOLEAN && uctl->type != SND_CONTROL_TYPE_INTEGER) {
+ if (uctl->type != SND_CONTROL_TYPE_ENUMERATED) {
error("A wrong type %i for the control '%s'. The type integer is expected. Skipping...", uctl->type, control_id(&uctl->c.id));
return 1;
}
for (idx = 0; idx < cctl->info.values_count; idx++) {
- if (cctl->info.value.enumerated.items <= uctl->c.value.integer.value[idx]) {
+ if (cctl->info.value.enumerated.items <= uctl->c.value.enumerated.item[idx]) {
error("The value %u for the control '%s' is out of range 0-%i.", uctl->c.value.integer.value[idx], control_id(&uctl->c.id), cctl->info.value.enumerated.items-1);
return 1;
}
- if (cctl->c.value.enumerated.item[idx] != uctl->c.value.integer.value[idx]) {
+ if (cctl->c.value.enumerated.item[idx] != uctl->c.value.enumerated.item[idx]) {
cctl->change = 1;
- cctl->c.value.enumerated.item[idx] = uctl->c.value.integer.value[idx];
+ cctl->c.value.enumerated.item[idx] = uctl->c.value.enumerated.item[idx];
}
}
break;
case SND_CONTROL_IFACE_SEQUENCER: s = "sequencer"; break;
default: sprintf(v, "%i", info.id.iface); s = v; break;
}
- fprintf(out, "%scontrol(%s, %i, %i, \"%s\", %i", space, s, info.id.device, info.id.subdevice, info.id.name, info.id.index);
- if (info.type == SND_CONTROL_TYPE_BYTES)
- fprintf(out, "rawdata(@");
+ fprintf(out, "%scontrol(ident={iface=%s", space, s);
+ if (info.id.device > 0)
+ fprintf(out, ", device=%i", info.id.device);
+ if (info.id.subdevice > 0)
+ fprintf(out, ", subdevice=%i", info.id.subdevice);
+ fprintf(out, ", name='%s'", info.id.name);
+ if (info.id.index > 0)
+ fprintf(out, ", index=%i", info.id.index);
+ fprintf(out, "}, ");
+ switch (info.type) {
+ case SND_CONTROL_TYPE_BOOLEAN: fprintf(out, "bool={"); break;
+ case SND_CONTROL_TYPE_INTEGER: fprintf(out, "int={"); break;
+ case SND_CONTROL_TYPE_ENUMERATED: fprintf(out, "enum={"); break;
+ case SND_CONTROL_TYPE_BYTES: fprintf(out, "byte={"); break;
+ default: break;
+ }
for (idx = 0; idx < info.values_count; idx++) {
+ if (idx > 0)
+ fprintf(out, ",");
switch (info.type) {
case SND_CONTROL_TYPE_BOOLEAN:
- fprintf(out, ", %s", control->c.value.integer.value[idx] ? "true" : "false");
+ fprintf(out, "%s", control->c.value.integer.value[idx] ? "true" : "false");
break;
case SND_CONTROL_TYPE_INTEGER:
- fprintf(out, ", %li", control->c.value.integer.value[idx]);
+ fprintf(out, "%li", control->c.value.integer.value[idx]);
break;
case SND_CONTROL_TYPE_ENUMERATED:
- fprintf(out, ", %u", control->c.value.enumerated.item[idx]);
+ fprintf(out, "%u", control->c.value.enumerated.item[idx]);
break;
case SND_CONTROL_TYPE_BYTES:
- if (idx > 0)
- fprintf(out, ":");
fprintf(out, "%02x", control->c.value.bytes.data[idx]);
break;
default:
break;
}
}
- if (info.type == SND_CONTROL_TYPE_BYTES)
- fprintf(out, ")");
- fprintf(out, ")\n");
+ fprintf(out, "})\n");
}
static void soundcard_setup_write_controls(FILE *out, const char *space, int card, struct ctl_control **controls)