From 50658ad2e73f2604c6d775535a69466f96a3f9fb Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 25 Jul 2000 15:17:55 +0000 Subject: [PATCH] Changed syntax of configuration file and added better parsing. --- alsactl/Makefile.am | 1 - alsactl/alsactl_lexer.l | 32 ++++----- alsactl/alsactl_parser.y | 142 +++++++++++++++++++++++++-------------- alsactl/merge.c | 12 ++-- alsactl/setup.c | 33 ++++++--- 5 files changed, 133 insertions(+), 87 deletions(-) diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am index a4ce4d2..3df5067 100644 --- a/alsactl/Makefile.am +++ b/alsactl/Makefile.am @@ -8,4 +8,3 @@ YFLAGS=-d # lexer / parser debug #CFLAGS=-pipe -g -DYYDEBUG #LFLAGS=-d - diff --git a/alsactl/alsactl_lexer.l b/alsactl/alsactl_lexer.l index 77be63c..7253c16 100644 --- a/alsactl/alsactl_lexer.l +++ b/alsactl/alsactl_lexer.l @@ -62,6 +62,18 @@ rawmidi return L_RAWMIDI; timer return L_TIMER; sequencer return L_SEQUENCER; +ident return L_IDENT; +iface return L_IFACE; +name return L_NAME; +device return L_DEVICE; +subdevice return L_SUBDEVICE; +index return L_INDEX; + +bool return L_BOOL; +int return L_INT; +enum return L_ENUM; +byte return L_BYTE; + /* boolean */ false|off|no return L_FALSE; @@ -72,26 +84,6 @@ true|on|yes return L_TRUE; [0-9]+ { yylval.i_value = strtol(yytext, (char **)NULL, 10); return L_INTEGER; } 0x[0-9a-f]+ { yylval.i_value = strtol(yytext, (char **)NULL, 0); return L_INTEGER; } - /* byte array */ - -"@"([0-9a-f]{2}:){0,31}([0-9a-f]{2})"@" { - char *p = yytext + 1, x[3]; - unsigned char *d; - int val; - yylval.a_value.data = d = (unsigned char *)malloc( 32 ); - yylval.a_value.datalen = 0; - while (*p) { - strncpy(x, p, 2); x[2] = '\0'; - sscanf(x, "%02x", &val); - *d++ = val; - ++yylval.a_value.datalen; - p += 2; - if (*p == '@') - break; - p++; - } - return L_BYTEARRAY; } - /* strings */ \"[^\"]*\" { yytext[strlen(yytext) - 1] = 0; diff --git a/alsactl/alsactl_parser.y b/alsactl/alsactl_parser.y index 586127a..8eef8ff 100644 --- a/alsactl/alsactl_parser.y +++ b/alsactl/alsactl_parser.y @@ -44,11 +44,16 @@ struct bytearray { 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 */ @@ -82,7 +87,8 @@ static snd_control_type_t Xtype = SND_CONTROL_TYPE_NONE; /* 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 boolean %type integer iface @@ -104,22 +110,42 @@ soundcards : | 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; } @@ -190,7 +216,7 @@ static void build_soundcard(char *name) 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; @@ -198,7 +224,6 @@ static void build_control_begin(int iface, unsigned int device, unsigned int sub first = &Xsoundcard->control.controls; Xcontrol = (struct ctl_control *)malloc(sizeof(struct ctl_control)); if (!Xcontrol) { - free(name); error_nomem(); return; } @@ -211,65 +236,84 @@ static void build_control_begin(int iface, unsigned int device, unsigned int sub } 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; -} diff --git a/alsactl/merge.c b/alsactl/merge.c index f276b1a..6a8487e 100644 --- a/alsactl/merge.c +++ b/alsactl/merge.c @@ -29,7 +29,7 @@ static int merge_one_control(struct ctl_control *cctl, struct ctl_control *uctl, 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; } @@ -41,7 +41,7 @@ static int merge_one_control(struct ctl_control *cctl, struct ctl_control *uctl, } 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; } @@ -58,18 +58,18 @@ static int merge_one_control(struct ctl_control *cctl, struct ctl_control *uctl, } 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; diff --git a/alsactl/setup.c b/alsactl/setup.c index b909aed..8385268 100644 --- a/alsactl/setup.c +++ b/alsactl/setup.c @@ -342,32 +342,43 @@ static void soundcard_setup_write_control(FILE * out, const char *space, int car 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) -- 2.47.1