OSDN Git Service

ucm: allow to ignore errors for the value substitution
authorJaroslav Kysela <perex@perex.cz>
Thu, 18 Jun 2020 13:09:23 +0000 (15:09 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 18 Jun 2020 14:06:12 +0000 (16:06 +0200)
It may be useful to ignore the errors where the environment
or sysfs values are not defined for the specific hardware.

Enhance substitution for 'syntax 3' so $${} substitution
means ignore the errors (return an empty string).

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/ucm/ucm_subs.c

index d501da3..b2a1845 100644 (file)
@@ -268,6 +268,7 @@ int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
        size_t size, nsize, idsize, rvalsize, dpos = 0;
        const char *tmp;
        char *r, *nr, *rval, v2[32];
+       bool ignore_error, allow_empty;
        int err;
 
        if (value == NULL)
@@ -279,62 +280,73 @@ int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
                return -ENOMEM;
 
        while (*value) {
-               if (*value == '$' && *(value+1) == '{') {
-                       bool allow_empty = false;
-
-                       MATCH_VARIABLE(value, "${OpenName}", rval_open_name, false);
-                       MATCH_VARIABLE(value, "${ConfTopDir}", rval_conf_topdir, false);
-                       MATCH_VARIABLE(value, "${ConfDir}", rval_conf_dir, false);
-                       MATCH_VARIABLE(value, "${ConfName}", rval_conf_name, false);
-                       MATCH_VARIABLE(value, "${CardNumber}", rval_card_number, true);
-                       MATCH_VARIABLE(value, "${CardId}", rval_card_id, false);
-                       MATCH_VARIABLE(value, "${CardDriver}", rval_card_driver, false);
-                       MATCH_VARIABLE(value, "${CardName}", rval_card_name, false);
-                       MATCH_VARIABLE(value, "${CardLongName}", rval_card_longname, false);
-                       MATCH_VARIABLE(value, "${CardComponents}", rval_card_components, true);
-                       MATCH_VARIABLE2(value, "${env:", rval_env);
-                       MATCH_VARIABLE2(value, "${sys:", rval_sysfs);
-                       MATCH_VARIABLE2(value, "${var:", rval_var);
-                       MATCH_VARIABLE2(value, "${CardIdByName:", rval_card_id_by_name);
-                       err = -EINVAL;
-                       tmp = strchr(value, '}');
-                       if (tmp) {
-                               strncpy(r, value, tmp + 1 - value);
-                               r[tmp + 1 - value] = '\0';
-                               uc_error("variable '%s' is not known!", r);
-                       } else {
-                               uc_error("variable reference '%s' is not complete", value);
+               if (*value != '$') {
+__std:
+                       r[dpos++] = *value;
+                       value++;
+                       continue;
+               }
+               ignore_error = false;
+               if (value[1] == '$' && value[2] == '{' && uc_mgr->conf_format >= 3) {
+                       value++;
+                       ignore_error = true;
+               } else if (value[1] != '{') {
+                       goto __std;
+               }
+               allow_empty = false;
+               MATCH_VARIABLE(value, "${OpenName}", rval_open_name, false);
+               MATCH_VARIABLE(value, "${ConfTopDir}", rval_conf_topdir, false);
+               MATCH_VARIABLE(value, "${ConfDir}", rval_conf_dir, false);
+               MATCH_VARIABLE(value, "${ConfName}", rval_conf_name, false);
+               MATCH_VARIABLE(value, "${CardNumber}", rval_card_number, true);
+               MATCH_VARIABLE(value, "${CardId}", rval_card_id, false);
+               MATCH_VARIABLE(value, "${CardDriver}", rval_card_driver, false);
+               MATCH_VARIABLE(value, "${CardName}", rval_card_name, false);
+               MATCH_VARIABLE(value, "${CardLongName}", rval_card_longname, false);
+               MATCH_VARIABLE(value, "${CardComponents}", rval_card_components, true);
+               MATCH_VARIABLE2(value, "${env:", rval_env);
+               MATCH_VARIABLE2(value, "${sys:", rval_sysfs);
+               MATCH_VARIABLE2(value, "${var:", rval_var);
+               MATCH_VARIABLE2(value, "${CardIdByName:", rval_card_id_by_name);
+               err = -EINVAL;
+               tmp = strchr(value, '}');
+               if (tmp) {
+                       strncpy(r, value, tmp + 1 - value);
+                       r[tmp + 1 - value] = '\0';
+                       uc_error("variable '%s' is not known!", r);
+               } else {
+                       uc_error("variable reference '%s' is not complete", value);
+               }
+               goto __error;
+__rval:
+               if (rval == NULL || (!allow_empty && rval[0] == '\0')) {
+                       free(rval);
+                       if (ignore_error) {
+                               value += idsize;
+                               continue;
                        }
+                       strncpy(r, value, idsize);
+                       r[idsize] = '\0';
+                       uc_error("variable '%s' is not defined in this context!", r);
+                       err = -EINVAL;
                        goto __error;
-__rval:
-                       if (rval == NULL || (!allow_empty && rval[0] == '\0')) {
+               }
+               value += idsize;
+               rvalsize = strlen(rval);
+               nsize = size + rvalsize - idsize;
+               if (nsize > size) {
+                       nr = realloc(r, nsize);
+                       if (nr == NULL) {
                                free(rval);
-                               strncpy(r, value, idsize);
-                               r[idsize] = '\0';
-                               uc_error("variable '%s' is not defined in this context!", r);
-                               err = -EINVAL;
+                               err = -ENOMEM;
                                goto __error;
                        }
-                       value += idsize;
-                       rvalsize = strlen(rval);
-                       nsize = size + rvalsize - idsize;
-                       if (nsize > size) {
-                               nr = realloc(r, nsize);
-                               if (nr == NULL) {
-                                       free(rval);
-                                       err = -ENOMEM;
-                                       goto __error;
-                               }
-                               size = nsize;
-                               r = nr;
-                       }
-                       strcpy(r + dpos, rval);
-                       dpos += rvalsize;
-                       free(rval);
-               } else {
-                       r[dpos++] = *value;
-                       value++;
+                       size = nsize;
+                       r = nr;
                }
+               strcpy(r + dpos, rval);
+               dpos += rvalsize;
+               free(rval);
        }
        r[dpos] = '\0';