]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Simplified evaluation using snd_config_walk. Fixed implementation
authorAbramo Bagnara <abramo@alsa-project.org>
Sat, 16 Jun 2001 08:19:15 +0000 (08:19 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Sat, 16 Jun 2001 08:19:15 +0000 (08:19 +0000)
include/conf.h
src/alsa.conf
src/conf.c
src/confmisc.c

index 12c115fe782c7cc770d5c765917589619ad4b046..415adf4bd0c209366bc57ade54c1e781200c12a6 100644 (file)
@@ -40,6 +40,8 @@ int snd_config_search_definition(snd_config_t *config,
 
 int snd_config_expand(snd_config_t *config, const char *args,
                      void *private_data, snd_config_t **result);
+int snd_config_evaluate(snd_config_t *config, void *private_data,
+                       snd_config_t **result);
 
 int snd_config_add(snd_config_t *config, snd_config_t *leaf);
 int snd_config_delete(snd_config_t *config);
index baf3a443e5d0203ce1ddbca979fcc7cbcbc1c346..9d824ce209ca1606cf6bc2d9dbadd3e67d1144f7 100644 (file)
@@ -10,9 +10,24 @@ pcm.hw {
        @args [ CARD DEV SUBDEV ]
        @args.CARD {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_PCM_CARD
+                               ALSA_CARD
+                       ]
+                       default 0
+               }
        }
        @args.DEV {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_PCM_DEVICE
+                       ]
+                       default 0
+               }
        }
        @args.SUBDEV {
                type integer
@@ -28,9 +43,24 @@ pcm.plughw {
        @args [ CARD DEV SUBDEV ]
        @args.CARD {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_PCM_CARD
+                               ALSA_CARD
+                       ]
+                       default 0
+               }
        }
        @args.DEV {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_PCM_DEVICE
+                       ]
+                       default 0
+               }
        }
        @args.SUBDEV {
                type integer
@@ -444,6 +474,14 @@ ctl.hw {
        @args[ CARD ]
        @args.CARD {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_CTL_CARD
+                               ALSA_CARD
+                       ]
+                       default 0
+               }
        }
        type hw
        card $(CARD)
@@ -465,8 +503,9 @@ ctl.shm {
 ctl.default {
        type hw
        card {
-               @func getenv
+               @func igetenv
                envname [
+                       ALSA_CTL_CARD
                        ALSA_CARD
                ]
                default 0
@@ -481,9 +520,24 @@ rawmidi.hw {
        @args [ CARD DEV SUBDEV ]
        @args.CARD {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_RAWMIDI_CARD
+                               ALSA_CARD
+                       ]
+                       default 0
+               }
        }
        @args.DEV {
                type integer
+               default {
+                       @func igetenv
+                       envname [
+                               ALSA_RAWMIDI_DEVICE
+                       ]
+                       default 0
+               }
        }
        @args.SUBDEV {
                type integer
index 263212e090755ced52fcb0a782690feaba4396ff..f6252f3c3e55134f85d44c6eb5cd1c8f263a653f 100644 (file)
@@ -1862,124 +1862,112 @@ static int _snd_config_expand(snd_config_t *src,
        return 1;
 }
 
-static int evaluate_node(snd_config_t *father, snd_config_t *src,
-                        void *private_data, snd_config_t **dst)
+void snd_config_substitute(snd_config_t *dst, snd_config_t *src)
 {
-       snd_config_iterator_t i, next;
-       const char *lib = NULL, *func = NULL;
-       int err;
-       char buf[64];
-       char *evaluate_name = NULL;
-       int (*evaluate_func)(snd_config_t **dst, snd_config_t *src, void *private_data);
-       void *h;
-
-       assert(father && src && dst);
+       free(dst->id);
+       dst->id = src->id;
+       dst->type = src->type;
+       dst->u = src->u;
+}
 
-       snd_config_for_each(i, next, src) {
-               snd_config_t *n = snd_config_iterator_entry(i);
-               const char *id;
-               if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
-                       snd_config_t *n1;
-                       err = evaluate_node(src, n, private_data, &n1);
-                       if (err < 0) {
-                               SNDERR("Error in node %s", snd_config_get_id(n));
-                               goto __error;
+static int _snd_config_evaluate(snd_config_t *src,
+                               snd_config_t **dst ATTRIBUTE_UNUSED,
+                               snd_config_walk_pass_t pass,
+                               void *private_data)
+{
+       int err;
+       if (pass == SND_CONFIG_WALK_PASS_PRE) {
+               char buf[256];
+               const char *lib = NULL, *func_name = NULL;
+               const char *str;
+               int (*func)(snd_config_t **dst, snd_config_t *src,
+                           void *private_data);
+               void *h;
+               snd_config_t *c, *eval, *func_conf = NULL;
+               err = snd_config_search(src, "@func", &c);
+               if (err < 0)
+                       return 1;
+               err = snd_config_get_string(c, &str);
+               if (err < 0) {
+                       SNDERR("Invalid type for @func");
+                       return err;
+               }
+               err = snd_config_search_definition(snd_config, "func", str, &func_conf);
+               if (err >= 0) {
+                       snd_config_iterator_t i, next;
+                       if (snd_config_get_type(func_conf) != SND_CONFIG_TYPE_COMPOUND) {
+                               SNDERR("Invalid type for func %s definition", str);
+                               goto _err;
                        }
-                       if (n1) {                       /* replace node */
-                               snd_config_delete(n);
-                               err = snd_config_add(src, n1);
-                               if (err < 0)
-                                       goto __error;
+                       snd_config_for_each(i, next, func_conf) {
+                               snd_config_t *n = snd_config_iterator_entry(i);
+                               const char *id = snd_config_get_id(n);
+                               if (strcmp(id, "comment") == 0)
+                                       continue;
+                               if (strcmp(id, "lib") == 0) {
+                                       err = snd_config_get_string(n, &lib);
+                                       if (err < 0) {
+                                               SNDERR("Invalid type for %s", id);
+                                               goto _err;
+                                       }
+                                       continue;
+                               }
+                               if (strcmp(id, "open") == 0) {
+                                       err = snd_config_get_string(n, &func_name);
+                                       if (err < 0) {
+                                               SNDERR("Invalid type for %s", id);
+                                               goto _err;
+                                       }
+                                       continue;
+                               }
+                               SNDERR("Unknown field %s", id);
+                       _err:
+                               snd_config_delete(func_conf);
+                               return -EINVAL;
                        }
                }
-               id = snd_config_get_id(n);
-               if (*id++ != '@')       /* quick look */
-                       continue;
-               if (!strcmp(id, "lib")) {
-                       if ((err = snd_config_get_string(n, &lib)) < 0) {
-                              _invalid_field:
-                               SNDERR("Unknown type of field %s", id);
-                               return err;
-                       }
-                       lib = strdup(lib);
-                       if (lib == NULL)
-                               goto __error;
-                       snd_config_delete(n);
-               } else if (!strcmp(id, "func")) {
-                       if ((err = snd_config_get_string(n, &func)) < 0)
-                               goto _invalid_field;
-                       func = strdup(func);
-                       if (func == NULL)
-                               goto __error;
-                       snd_config_delete(n);
+               if (!func_name) {
+                       func_name = buf;
+                       snprintf(buf, sizeof(buf), "snd_func_%s", str);
+               }
+               if (!lib)
+                       lib = ALSA_LIB;
+               h = dlopen(lib, RTLD_NOW);
+               if (h)
+                       func = dlsym(h, func_name);
+               if (func_conf)
+                       snd_config_delete(func_conf);
+               if (!h) {
+                       SNDERR("Cannot open shared library %s", lib);
+                       return -ENOENT;
                }
-       }
-       
-       if (func == NULL) {
-               *dst = NULL;
-               return 0;
-       }
-
-       if (evaluate_name == NULL) {
-               snprintf(buf, sizeof(buf), "snd_func_%s", func);
-               buf[sizeof(buf) - 1] = '\0';
-               evaluate_name = buf;
-       }
-       
-       h = dlopen(lib, RTLD_NOW);
-       if (!h) {
-               SNDERR("Cannot open shared library %s", lib);
-               err = -ENOENT;
-               goto __error;
-       }
-       evaluate_func = dlsym(h, evaluate_name);
-       if (!evaluate_func) {
+               if (!func) {
+                       SNDERR("symbol %s is not defined inside %s", func_name, lib);
+                       dlclose(h);
+                       return -ENXIO;
+               }
+               err = func(&eval, src, private_data);
                dlclose(h);
-               SNDERR("symbol %s is not defined inside %s", evaluate_name, lib ? lib : ALSA_LIB);
-               err = -ENXIO;
-               goto __error;
-       }
-       err = evaluate_func(dst, src, private_data);
-       dlclose(h);
-       if (err < 0) {
-               SNDERR("function %s returned error: %s", evaluate_name, snd_strerror(err));
-               goto __error;
+               if (err < 0) {
+                       SNDERR("function %s returned error: %s", func_name, snd_strerror(err));
+                       return err;
+               }
+               if (eval) {
+                       snd_config_substitute(src, eval);
+                       free(eval);
+               }
+               return 0;
        }
-       err = 0;
-
-      __error:
-       if (func)
-               free((void *)func);
-       if (lib)
-               free((void *)lib);
-       return err;
+       return 1;
 }
 
-int snd_config_evaluate(snd_config_t *conf, void *private_data)
-{
-       snd_config_iterator_t i, next;
 
-       assert(conf);
-       if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
-               return 0;
-       snd_config_for_each(i, next, conf) {
-               snd_config_t *n = snd_config_iterator_entry(i);
-               if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
-                       snd_config_t *n1;
-                       int err = evaluate_node(conf, n, private_data, &n1);
-                       if (err < 0) {
-                               SNDERR("Error in node %s", snd_config_get_id(n));
-                               return err;
-                       }
-                       if (n1) {                       /* replace node */
-                               snd_config_delete(n);
-                               err = snd_config_add(conf, n1);
-                               if (err < 0)
-                                       return err;
-                       }
-               }
-       }
-       return 0;
+int snd_config_evaluate(snd_config_t *config, void *private_data,
+                       snd_config_t **result)
+{
+       /* FIXME: Only in place evaluation is currently implemented */
+       assert(result == NULL);
+       return snd_config_walk(config, result, _snd_config_evaluate, private_data);
 }
 
 static int load_defaults(snd_config_t *subs, snd_config_t *defs)
@@ -2383,13 +2371,18 @@ int snd_config_expand(snd_config_t *config, const char *args,
                        SNDERR("Parse arguments error: %s", snd_strerror(err));
                        goto _end;
                }
+               err = snd_config_evaluate(subs, private_data, NULL);
+               if (err < 0) {
+                       SNDERR("Args evaluate error: %s", snd_strerror(err));
+                       goto _end;
+               }
                err = snd_config_walk(config, &res, _snd_config_expand, subs);
                if (err < 0) {
                        SNDERR("Expand error (walk): %s", snd_strerror(err));
                        goto _end;
                }
        }
-       err = snd_config_evaluate(res, private_data);
+       err = snd_config_evaluate(res, private_data, NULL);
        if (err < 0) {
                SNDERR("Evaluate error: %s", snd_strerror(err));
                snd_config_delete(res);
@@ -2429,7 +2422,7 @@ int snd_config_search_definition(snd_config_t *config,
                memcpy(key, name, args - name - 1);
                key[args - name - 1] = '\0';
        } else {
-               key = (char *) base;
+               key = (char *) name;
        } 
        err = snd_config_search_alias(config, base, key, &conf);
        if (err < 0)
index f2aee2be22db84a8c2eb6a95e585f984f1ab8d93..f28c798a621b1adc62d30536a798e6553b446226 100644 (file)
@@ -213,24 +213,31 @@ int snd_config_string_replace(const char *src, char idchr,
 
 int snd_func_getenv(snd_config_t **dst, snd_config_t *src, void *private_data)
 {
-       snd_config_t *n, *d, *e;
+       snd_config_t *n, *d;
        snd_config_iterator_t i, next;
        char *res, *def = NULL;
        int idx = 0, err;
        
-       err = snd_config_expand(src, NULL, private_data, &e);
-       if (err < 0)
-               return err;
-       err = snd_config_search(e, "envname", &n);
+       err = snd_config_search(src, "envname", &n);
        if (err < 0) {
                SNDERR("field envname not found");
                goto __error;
        }
-       err = snd_config_search(e, "default", &d);
+       err = snd_config_evaluate(n, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating envname");
+               goto __error;
+       }
+       err = snd_config_search(src, "default", &d);
        if (err < 0) {
                SNDERR("field default not found");
                goto __error;
        }
+       err = snd_config_evaluate(d, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating default");
+               goto __error;
+       }
        err = snd_config_get_ascii(d, &def);
        if (err < 0) {
                SNDERR("error getting field default");
@@ -277,7 +284,6 @@ int snd_func_getenv(snd_config_t **dst, snd_config_t *src, void *private_data)
       __error:
        if (def)
                free(def);
-       snd_config_delete(e);
        return err;
 }
 
@@ -303,7 +309,6 @@ int snd_func_igetenv(snd_config_t **dst, snd_config_t *src, void *private_data)
        err = 0;
 
  _end:
-       snd_config_delete(d);
        return err;
 }
        
@@ -311,19 +316,21 @@ int snd_func_igetenv(snd_config_t **dst, snd_config_t *src, void *private_data)
 
 int snd_func_concat(snd_config_t **dst, snd_config_t *src, void *private_data)
 {
-       snd_config_t *n, *e;
+       snd_config_t *n;
        snd_config_iterator_t i, next;
        char *res = NULL, *tmp;
        int idx = 0, len = 0, len1, err;
        
-       err = snd_config_expand(src, NULL, private_data, &e);
-       if (err < 0)
-               return err;
-       err = snd_config_search(e, "strings", &n);
+       err = snd_config_search(src, "strings", &n);
        if (err < 0) {
                SNDERR("field strings not found");
                goto __error;
        }
+       err = snd_config_evaluate(n, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating strings");
+               goto __error;
+       }
       __retry:
        snd_config_for_each(i, next, n) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -366,7 +373,6 @@ int snd_func_concat(snd_config_t **dst, snd_config_t *src, void *private_data)
                snd_config_set_string(*dst, res);
        free(res);
       __error:
-       snd_config_delete(e);
        return err;
 }
 
@@ -402,21 +408,23 @@ static int string_from_integer(char **dst, long v)
 
 int snd_func_card_strtype(snd_config_t **dst, snd_config_t *src, void *private_data)
 {
-       snd_config_t *n, *e;
+       snd_config_t *n;
        char *res = NULL;
        snd_ctl_t *ctl = NULL;
        snd_ctl_card_info_t *info;
        long v;
        int err;
        
-       err = snd_config_expand(src, NULL, private_data, &e);
-       if (err < 0)
-               return err;
-       err = snd_config_search(e, "card", &n);
+       err = snd_config_search(src, "card", &n);
        if (err < 0) {
                SNDERR("field card not found");
                goto __error;
        }
+       err = snd_config_evaluate(n, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating card");
+               goto __error;
+       }
        err = snd_config_get_integer(n, &v);
        if (err < 0) {
                SNDERR("field card is not an integer");
@@ -445,27 +453,28 @@ int snd_func_card_strtype(snd_config_t **dst, snd_config_t *src, void *private_d
       __error:
        if (ctl)
                snd_ctl_close(ctl);
-       snd_config_delete(e);
        return err;
 }
 
 int snd_func_card_id(snd_config_t **dst, snd_config_t *src, void *private_data)
 {
-       snd_config_t *n, *e;
+       snd_config_t *n;
        char *res = NULL;
        snd_ctl_t *ctl = NULL;
        snd_ctl_card_info_t *info;
        long v;
        int err;
        
-       err = snd_config_expand(src, NULL, private_data, &e);
-       if (err < 0)
-               return err;
-       err = snd_config_search(e, "card", &n);
+       err = snd_config_search(src, "card", &n);
        if (err < 0) {
                SNDERR("field card not found");
                goto __error;
        }
+       err = snd_config_evaluate(n, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating card");
+               goto __error;
+       }
        err = snd_config_get_integer(n, &v);
        if (err < 0) {
                SNDERR("field card is not an integer");
@@ -494,43 +503,54 @@ int snd_func_card_id(snd_config_t **dst, snd_config_t *src, void *private_data)
       __error:
        if (ctl)
                snd_ctl_close(ctl);
-       snd_config_delete(e);
        return err;
 }
 
 int snd_func_pcm_id(snd_config_t **dst, snd_config_t *src, void *private_data)
 {
-       snd_config_t *n, *e;
+       snd_config_t *n;
        char *res = NULL;
        snd_ctl_t *ctl = NULL;
        snd_pcm_info_t *info;
        long card, device, subdevice = 0;
        int err;
        
-       err = snd_config_expand(src, NULL, private_data, &e);
-       if (err < 0)
-               return err;
-       err = snd_config_search(e, "card", &n);
+       err = snd_config_search(src, "card", &n);
        if (err < 0) {
                SNDERR("field card not found");
                goto __error;
        }
+       err = snd_config_evaluate(n, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating card");
+               goto __error;
+       }
        err = snd_config_get_integer(n, &card);
        if (err < 0) {
                SNDERR("field card is not an integer");
                goto __error;
        }
-       err = snd_config_search(e, "device", &n);
+       err = snd_config_search(src, "device", &n);
        if (err < 0) {
                SNDERR("field device not found");
                goto __error;
        }
+       err = snd_config_evaluate(n, private_data, NULL);
+       if (err < 0) {
+               SNDERR("error evaluating device");
+               goto __error;
+       }
        err = snd_config_get_integer(n, &device);
        if (err < 0) {
                SNDERR("field device is not an integer");
                goto __error;
        }
-       if (snd_config_search(e, "subdevice", &n) >= 0) {
+       if (snd_config_search(src, "subdevice", &n) >= 0) {
+               err = snd_config_evaluate(n, private_data, NULL);
+               if (err < 0) {
+                       SNDERR("error evaluating subdevice");
+                       goto __error;
+               }
                err = snd_config_get_integer(n, &subdevice);
                if (err < 0) {
                        SNDERR("field subdevice is not an integer");
@@ -562,30 +582,35 @@ int snd_func_pcm_id(snd_config_t **dst, snd_config_t *src, void *private_data)
       __error:
        if (ctl)
                snd_ctl_close(ctl);
-       snd_config_delete(e);
        return err;
 }
 
 int snd_func_refer(snd_config_t **dst, snd_config_t *src, void *private_data)
 {
-       snd_config_t *n, *e;
+       snd_config_t *n;
        snd_config_t *root = NULL;
        const char *file = NULL, *name = NULL;
        int err;
        
-       err = snd_config_expand(src, NULL, private_data, &e);
-       if (err < 0)
-               return err;
-       err = snd_config_search(e, "file", &n);
+       err = snd_config_search(src, "file", &n);
        if (err >= 0) {
+               err = snd_config_evaluate(n, private_data, NULL);
+               if (err < 0) {
+                       SNDERR("error evaluating file");
+                       goto _end;
+               }
                err = snd_config_get_string(n, &file);
                if (err < 0) {
                        SNDERR("file is not a string");
                        goto _end;
                }
        }
-       err = snd_config_search(e, "name", &n);
+       err = snd_config_search(src, "name", &n);
        if (err >= 0) {
+               if (err < 0) {
+                       SNDERR("error evaluating name");
+                       goto _end;
+               }
                err = snd_config_get_string(n, &name);
                if (err < 0) {
                        SNDERR("name is not a string");