summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2020-06-18 15:09:23 +0200
committerJaroslav Kysela <perex@perex.cz>2020-06-18 16:06:12 +0200
commite6be54422709b3d18828a000c86b4b09d7511f84 (patch)
tree27261b3244c6f6f0056e82ffd41dc87083784c52
parent20e003a63d14edabd59e40e5d0b8ed2f11f8c9b8 (diff)
downloadalsa-lib-e6be54422709b3d18828a000c86b4b09d7511f84.tar.gz
ucm: allow to ignore errors for the value substitution
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>
-rw-r--r--src/ucm/ucm_subs.c112
1 files changed, 62 insertions, 50 deletions
diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
index d501da34..b2a1845c 100644
--- a/src/ucm/ucm_subs.c
+++ b/src/ucm/ucm_subs.c
@@ -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';