]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Changed syntax of configuration file and added better parsing.
authorJaroslav Kysela <perex@perex.cz>
Tue, 25 Jul 2000 15:17:55 +0000 (15:17 +0000)
committerJaroslav Kysela <perex@perex.cz>
Tue, 25 Jul 2000 15:17:55 +0000 (15:17 +0000)
alsactl/Makefile.am
alsactl/alsactl_lexer.l
alsactl/alsactl_parser.y
alsactl/merge.c
alsactl/setup.c

index a4ce4d2af601311bdac3e99cf15ed14edd5157dd..3df506744fc6d2a81ac5bcde009298fa473edf6f 100644 (file)
@@ -8,4 +8,3 @@ YFLAGS=-d
 # lexer / parser debug
 #CFLAGS=-pipe -g -DYYDEBUG
 #LFLAGS=-d
-
index 77be63c29e59fda8d038ab5dc033646025ef609e..7253c1645401f9c763efbac046853ea07ac9ff41 100644 (file)
@@ -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;
index 586127a13f6020e36f59618a1abe687425b0b65c..8eef8ffcc4dc6103b99b564d936d1a27509e5176 100644 (file)
@@ -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 <b_value> boolean
 %type <i_value> 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;
-}
index f276b1a607d5ea64a6d2c11c421fd9ee54de59af..6a8487e47f7f42a71a7d6715caecab19f32eaee7 100644 (file)
@@ -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;
index b909aed882bd38150ca4dd12b0d7b3899aaeaae3..8385268fc1107566b81808494328d9518d8b4018 100644 (file)
@@ -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)