Lines 71-90
static char *rval_conf_name(snd_use_case_mgr_t *uc_mgr)
Link Here
|
71 |
return NULL; |
71 |
return NULL; |
72 |
} |
72 |
} |
73 |
|
73 |
|
74 |
static char *rval_card_number(snd_use_case_mgr_t *uc_mgr) |
74 |
static char *get_card_number(struct ctl_list *ctl_list) |
75 |
{ |
75 |
{ |
76 |
struct ctl_list *ctl_list; |
|
|
77 |
char num[16]; |
76 |
char num[16]; |
78 |
|
77 |
|
79 |
if (uc_mgr->conf_format < 3) |
|
|
80 |
return NULL; |
81 |
ctl_list = uc_mgr_get_master_ctl(uc_mgr); |
82 |
if (ctl_list == NULL) |
78 |
if (ctl_list == NULL) |
83 |
return strdup(""); |
79 |
return strdup(""); |
84 |
snprintf(num, sizeof(num), "%i", snd_ctl_card_info_get_card(ctl_list->ctl_info)); |
80 |
snprintf(num, sizeof(num), "%i", snd_ctl_card_info_get_card(ctl_list->ctl_info)); |
85 |
return strdup(num); |
81 |
return strdup(num); |
86 |
} |
82 |
} |
87 |
|
83 |
|
|
|
84 |
static char *rval_card_number(snd_use_case_mgr_t *uc_mgr) |
85 |
{ |
86 |
if (uc_mgr->conf_format < 3) |
87 |
return NULL; |
88 |
return get_card_number(uc_mgr_get_master_ctl(uc_mgr)); |
89 |
} |
90 |
|
88 |
static char *rval_card_id(snd_use_case_mgr_t *uc_mgr) |
91 |
static char *rval_card_id(snd_use_case_mgr_t *uc_mgr) |
89 |
{ |
92 |
{ |
90 |
struct ctl_list *ctl_list; |
93 |
struct ctl_list *ctl_list; |
Lines 135-151
static char *rval_card_components(snd_use_case_mgr_t *uc_mgr)
Link Here
|
135 |
return strdup(snd_ctl_card_info_get_components(ctl_list->ctl_info)); |
138 |
return strdup(snd_ctl_card_info_get_components(ctl_list->ctl_info)); |
136 |
} |
139 |
} |
137 |
|
140 |
|
138 |
static char *rval_card_id_by_name(snd_use_case_mgr_t *uc_mgr, const char *id) |
141 |
static struct ctl_list *get_ctl_list_by_name(snd_use_case_mgr_t *uc_mgr, const char *id) |
139 |
{ |
142 |
{ |
140 |
struct ctl_list *ctl_list; |
|
|
141 |
char *name, *index; |
143 |
char *name, *index; |
142 |
long idx = 0; |
144 |
long idx = 0; |
143 |
|
145 |
|
144 |
if (uc_mgr->conf_format < 3) { |
|
|
145 |
uc_error("CardIdByName substitution is supported in v3+ syntax"); |
146 |
return NULL; |
147 |
} |
148 |
|
149 |
name = alloca(strlen(id) + 1); |
146 |
name = alloca(strlen(id) + 1); |
150 |
strcpy(name, id); |
147 |
strcpy(name, id); |
151 |
index = strchr(name, '#'); |
148 |
index = strchr(name, '#'); |
Lines 154-160
static char *rval_card_id_by_name(snd_use_case_mgr_t *uc_mgr, const char *id)
Link Here
|
154 |
if (safe_strtol(index + 1, &idx)) |
151 |
if (safe_strtol(index + 1, &idx)) |
155 |
return NULL; |
152 |
return NULL; |
156 |
} |
153 |
} |
157 |
ctl_list = uc_mgr_get_ctl_by_name(uc_mgr, name, idx); |
154 |
return uc_mgr_get_ctl_by_name(uc_mgr, name, idx); |
|
|
155 |
} |
156 |
|
157 |
static char *rval_card_number_by_name(snd_use_case_mgr_t *uc_mgr, const char *id) |
158 |
{ |
159 |
if (uc_mgr->conf_format < 3) { |
160 |
uc_error("CardNumberByName substitution is supported in v3+ syntax"); |
161 |
return NULL; |
162 |
} |
163 |
|
164 |
return get_card_number(get_ctl_list_by_name(uc_mgr, id)); |
165 |
} |
166 |
|
167 |
static char *rval_card_id_by_name(snd_use_case_mgr_t *uc_mgr, const char *id) |
168 |
{ |
169 |
struct ctl_list *ctl_list; |
170 |
|
171 |
if (uc_mgr->conf_format < 3) { |
172 |
uc_error("CardIdByName substitution is supported in v3+ syntax"); |
173 |
return NULL; |
174 |
} |
175 |
|
176 |
ctl_list = get_ctl_list_by_name(uc_mgr, id); |
158 |
if (ctl_list == NULL) |
177 |
if (ctl_list == NULL) |
159 |
return NULL; |
178 |
return NULL; |
160 |
return strdup(snd_ctl_card_info_get_id(ctl_list->ctl_info)); |
179 |
return strdup(snd_ctl_card_info_get_id(ctl_list->ctl_info)); |
Lines 246-264
static char *rval_var(snd_use_case_mgr_t *uc_mgr, const char *id)
Link Here
|
246 |
#define MATCH_VARIABLE2(name, id, fcn) \ |
265 |
#define MATCH_VARIABLE2(name, id, fcn) \ |
247 |
if (strncmp((name), (id), sizeof(id) - 1) == 0) { \ |
266 |
if (strncmp((name), (id), sizeof(id) - 1) == 0) { \ |
248 |
idsize = sizeof(id) - 1; \ |
267 |
idsize = sizeof(id) - 1; \ |
249 |
tmp = strchr(value + idsize, '}'); \ |
268 |
fcn2 = (fcn); \ |
250 |
if (tmp) { \ |
269 |
goto __match2; \ |
251 |
rvalsize = tmp - (value + idsize); \ |
|
|
252 |
if (rvalsize > sizeof(v2)) { \ |
253 |
err = -ENOMEM; \ |
254 |
goto __error; \ |
255 |
} \ |
256 |
strncpy(v2, value + idsize, rvalsize); \ |
257 |
v2[rvalsize] = '\0'; \ |
258 |
idsize += rvalsize + 1; \ |
259 |
rval = fcn(uc_mgr, v2); \ |
260 |
goto __rval; \ |
261 |
} \ |
262 |
} |
270 |
} |
263 |
|
271 |
|
264 |
int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr, |
272 |
int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr, |
Lines 267-273
int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
Link Here
|
267 |
{ |
275 |
{ |
268 |
size_t size, nsize, idsize, rvalsize, dpos = 0; |
276 |
size_t size, nsize, idsize, rvalsize, dpos = 0; |
269 |
const char *tmp; |
277 |
const char *tmp; |
270 |
char *r, *nr, *rval, v2[32]; |
278 |
char *r, *nr, *rval, v2[48]; |
|
|
279 |
bool ignore_error, allow_empty; |
280 |
char *(*fcn2)(snd_use_case_mgr_t *, const char *id); |
271 |
int err; |
281 |
int err; |
272 |
|
282 |
|
273 |
if (value == NULL) |
283 |
if (value == NULL) |
Lines 279-340
int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
Link Here
|
279 |
return -ENOMEM; |
289 |
return -ENOMEM; |
280 |
|
290 |
|
281 |
while (*value) { |
291 |
while (*value) { |
282 |
if (*value == '$' && *(value+1) == '{') { |
292 |
if (*value != '$') { |
283 |
bool allow_empty = false; |
293 |
__std: |
284 |
|
294 |
r[dpos++] = *value; |
285 |
MATCH_VARIABLE(value, "${OpenName}", rval_open_name, false); |
295 |
value++; |
286 |
MATCH_VARIABLE(value, "${ConfTopDir}", rval_conf_topdir, false); |
296 |
continue; |
287 |
MATCH_VARIABLE(value, "${ConfDir}", rval_conf_dir, false); |
297 |
} |
288 |
MATCH_VARIABLE(value, "${ConfName}", rval_conf_name, false); |
298 |
ignore_error = false; |
289 |
MATCH_VARIABLE(value, "${CardNumber}", rval_card_number, true); |
299 |
if (value[1] == '$' && value[2] == '{' && uc_mgr->conf_format >= 3) { |
290 |
MATCH_VARIABLE(value, "${CardId}", rval_card_id, false); |
300 |
value++; |
291 |
MATCH_VARIABLE(value, "${CardDriver}", rval_card_driver, false); |
301 |
ignore_error = true; |
292 |
MATCH_VARIABLE(value, "${CardName}", rval_card_name, false); |
302 |
} else if (value[1] != '{') { |
293 |
MATCH_VARIABLE(value, "${CardLongName}", rval_card_longname, false); |
303 |
goto __std; |
294 |
MATCH_VARIABLE(value, "${CardComponents}", rval_card_components, true); |
304 |
} |
295 |
MATCH_VARIABLE2(value, "${env:", rval_env); |
305 |
allow_empty = false; |
296 |
MATCH_VARIABLE2(value, "${sys:", rval_sysfs); |
306 |
fcn2 = NULL; |
297 |
MATCH_VARIABLE2(value, "${var:", rval_var); |
307 |
MATCH_VARIABLE(value, "${OpenName}", rval_open_name, false); |
298 |
MATCH_VARIABLE2(value, "${CardIdByName:", rval_card_id_by_name); |
308 |
MATCH_VARIABLE(value, "${ConfTopDir}", rval_conf_topdir, false); |
299 |
err = -EINVAL; |
309 |
MATCH_VARIABLE(value, "${ConfDir}", rval_conf_dir, false); |
300 |
tmp = strchr(value, '}'); |
310 |
MATCH_VARIABLE(value, "${ConfName}", rval_conf_name, false); |
301 |
if (tmp) { |
311 |
MATCH_VARIABLE(value, "${CardNumber}", rval_card_number, true); |
302 |
strncpy(r, value, tmp + 1 - value); |
312 |
MATCH_VARIABLE(value, "${CardId}", rval_card_id, false); |
303 |
r[tmp + 1 - value] = '\0'; |
313 |
MATCH_VARIABLE(value, "${CardDriver}", rval_card_driver, false); |
304 |
uc_error("variable '%s' is not known!", r); |
314 |
MATCH_VARIABLE(value, "${CardName}", rval_card_name, false); |
|
|
315 |
MATCH_VARIABLE(value, "${CardLongName}", rval_card_longname, false); |
316 |
MATCH_VARIABLE(value, "${CardComponents}", rval_card_components, true); |
317 |
MATCH_VARIABLE2(value, "${env:", rval_env); |
318 |
MATCH_VARIABLE2(value, "${sys:", rval_sysfs); |
319 |
MATCH_VARIABLE2(value, "${var:", rval_var); |
320 |
MATCH_VARIABLE2(value, "${CardNumberByName:", rval_card_number_by_name); |
321 |
MATCH_VARIABLE2(value, "${CardIdByName:", rval_card_id_by_name); |
322 |
__merr: |
323 |
err = -EINVAL; |
324 |
tmp = strchr(value, '}'); |
325 |
if (tmp) { |
326 |
strncpy(r, value, tmp + 1 - value); |
327 |
r[tmp + 1 - value] = '\0'; |
328 |
uc_error("variable '%s' is not known!", r); |
329 |
} else { |
330 |
uc_error("variable reference '%s' is not complete", value); |
331 |
} |
332 |
goto __error; |
333 |
__match2: |
334 |
tmp = strchr(value + idsize, '}'); |
335 |
if (tmp) { |
336 |
rvalsize = tmp - (value + idsize); |
337 |
if (rvalsize > sizeof(v2)) { |
338 |
err = -ENOMEM; |
339 |
goto __error; |
340 |
} |
341 |
strncpy(v2, value + idsize, rvalsize); |
342 |
v2[rvalsize] = '\0'; |
343 |
idsize += rvalsize + 1; |
344 |
if (*v2 == '$' && uc_mgr->conf_format >= 3) { |
345 |
tmp = uc_mgr_get_variable(uc_mgr, v2 + 1); |
346 |
if (tmp == NULL) { |
347 |
uc_error("define '%s' is not reachable in this context!", v2 + 1); |
348 |
rval = NULL; |
349 |
} else { |
350 |
rval = fcn2(uc_mgr, tmp); |
351 |
} |
305 |
} else { |
352 |
} else { |
306 |
uc_error("variable reference '%s' is not complete", value); |
353 |
rval = fcn2(uc_mgr, v2); |
307 |
} |
354 |
} |
308 |
goto __error; |
355 |
goto __rval; |
|
|
356 |
} |
357 |
goto __merr; |
309 |
__rval: |
358 |
__rval: |
310 |
if (rval == NULL || (!allow_empty && rval[0] == '\0')) { |
359 |
if (rval == NULL || (!allow_empty && rval[0] == '\0')) { |
|
|
360 |
free(rval); |
361 |
if (ignore_error) { |
362 |
value += idsize; |
363 |
continue; |
364 |
} |
365 |
strncpy(r, value, idsize); |
366 |
r[idsize] = '\0'; |
367 |
uc_error("variable '%s' is not defined in this context!", r); |
368 |
err = -EINVAL; |
369 |
goto __error; |
370 |
} |
371 |
value += idsize; |
372 |
rvalsize = strlen(rval); |
373 |
nsize = size + rvalsize - idsize; |
374 |
if (nsize > size) { |
375 |
nr = realloc(r, nsize); |
376 |
if (nr == NULL) { |
311 |
free(rval); |
377 |
free(rval); |
312 |
strncpy(r, value, idsize); |
378 |
err = -ENOMEM; |
313 |
r[idsize] = '\0'; |
|
|
314 |
uc_error("variable '%s' is not defined in this context!", r); |
315 |
err = -EINVAL; |
316 |
goto __error; |
379 |
goto __error; |
317 |
} |
380 |
} |
318 |
value += idsize; |
381 |
size = nsize; |
319 |
rvalsize = strlen(rval); |
382 |
r = nr; |
320 |
nsize = size + rvalsize - idsize; |
|
|
321 |
if (nsize > size) { |
322 |
nr = realloc(r, nsize); |
323 |
if (nr == NULL) { |
324 |
free(rval); |
325 |
err = -ENOMEM; |
326 |
goto __error; |
327 |
} |
328 |
size = nsize; |
329 |
r = nr; |
330 |
} |
331 |
strcpy(r + dpos, rval); |
332 |
dpos += rvalsize; |
333 |
free(rval); |
334 |
} else { |
335 |
r[dpos++] = *value; |
336 |
value++; |
337 |
} |
383 |
} |
|
|
384 |
strcpy(r + dpos, rval); |
385 |
dpos += rvalsize; |
386 |
free(rval); |
338 |
} |
387 |
} |
339 |
r[dpos] = '\0'; |
388 |
r[dpos] = '\0'; |
340 |
|
389 |
|