/** * \brief Returns an environment value. * \param dst The function puts the handle to the result configuration node * (with type string) at the address specified by \p dst. * \param root Handle to the root source node. * \param src Handle to the source node, with definitions for \c vars and * \c default. * \param private_data Handle to the \c private_data node. * \return Zero if successful, otherwise a negative error code. * * Example: \code { @func getenv vars [ MY_CARD CARD C ] default 0 } \endcode */ int snd_func_getenv(snd_config_t **dst, snd_config_t *root, snd_config_t *src, snd_config_t *private_data) { snd_config_t *n, *d; snd_config_iterator_t i, next; const char *res, *id; char *def = NULL; int idx = 0, err, hit; err = snd_config_search(src, "vars", &n); if (err < 0) { SNDERR("field vars not found"); goto __error; } err = snd_config_evaluate(n, root, private_data, NULL); if (err < 0) { SNDERR("error evaluating vars"); goto __error; } err = snd_config_search(src, "default", &d); if (err < 0) { SNDERR("field default not found"); goto __error; } err = snd_config_evaluate(d, root, 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"); goto __error; } do { hit = 0; snd_config_for_each(i, next, n) { snd_config_t *n = snd_config_iterator_entry(i); const char *ptr; long i; if (snd_config_get_id(n, &id) < 0) continue; if (snd_config_get_type(n) != SND_CONFIG_TYPE_STRING) { SNDERR("field %s is not a string", id); err = -EINVAL; goto __error; } err = safe_strtol(id, &i); if (err < 0) { SNDERR("id of field %s is not an integer", id); err = -EINVAL; goto __error; } if (i == idx) { idx++; err = snd_config_get_string(n, &ptr); if (err < 0) { SNDERR("invalid string for id %s", id); err = -EINVAL; goto __error; } res = getenv(ptr); if (res != NULL && *res != '\0') goto __ok; hit = 1; } } } while (hit); res = def; __ok: err = snd_config_get_id(src, &id); if (err >= 0) err = snd_config_imake_string(dst, id, res); __error: free(def); return err; }
/** * \brief Merges the given strings. * \param dst The function puts the handle to the result configuration node * (with type string) at the address specified by \p dst. * \param root Handle to the root source node. * \param src Handle to the source node, with a definition for \c strings. * \param private_data Handle to the \c private_data node. * \return A non-negative value if successful, otherwise a negative error code. * * Example (result is "a1b2c3"): \code { @func concat strings [ "a1" "b2" "c3" ] } \endcode */ int snd_func_concat(snd_config_t **dst, snd_config_t *root, snd_config_t *src, snd_config_t *private_data) { snd_config_t *n; snd_config_iterator_t i, next; const char *id; char *res = NULL, *tmp; int idx = 0, len = 0, len1, err, hit; err = snd_config_search(src, "strings", &n); if (err < 0) { SNDERR("field strings not found"); goto __error; } err = snd_config_evaluate(n, root, private_data, NULL); if (err < 0) { SNDERR("error evaluating strings"); goto __error; } do { hit = 0; snd_config_for_each(i, next, n) { snd_config_t *n = snd_config_iterator_entry(i); char *ptr; const char *id; long i; if (snd_config_get_id(n, &id) < 0) continue; err = safe_strtol(id, &i); if (err < 0) { SNDERR("id of field %s is not an integer", id); err = -EINVAL; goto __error; } if (i == idx) { idx++; err = snd_config_get_ascii(n, &ptr); if (err < 0) { SNDERR("invalid ascii string for id %s", id); err = -EINVAL; goto __error; } len1 = strlen(ptr); tmp = realloc(res, len + len1 + 1); if (tmp == NULL) { free(ptr); free(res); err = -ENOMEM; goto __error; } memcpy(tmp + len, ptr, len1); free(ptr); len += len1; tmp[len] = '\0'; res = tmp; hit = 1; } } } while (hit); if (res == NULL) { SNDERR("empty string is not accepted"); err = -EINVAL; goto __error; } err = snd_config_get_id(src, &id); if (err >= 0) err = snd_config_imake_string(dst, id, res); free(res); __error: return err; }
/** * \brief Creates a new File PCM * \param pcmp Returns created PCM handle * \param name Name of PCM * \param root Root configuration node * \param conf Configuration node with File PCM description * \param stream Stream type * \param mode Stream mode * \retval zero on success otherwise a negative error code * \warning Using of this function might be dangerous in the sense * of compatibility reasons. The prototype might be freely * changed in future. */ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, snd_config_t *root, snd_config_t *conf, snd_pcm_stream_t stream, int mode) { snd_config_iterator_t i, next; int err; snd_pcm_t *spcm; snd_config_t *slave = NULL, *sconf; const char *fname = NULL, *ifname = NULL; const char *format = NULL; long fd = -1, ifd = -1; int perm = 0600; snd_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); const char *id; if (snd_config_get_id(n, &id) < 0) continue; if (snd_pcm_conf_generic_id(id)) continue; if (strcmp(id, "slave") == 0) { slave = n; continue; } if (strcmp(id, "format") == 0) { err = snd_config_get_string(n, &format); if (err < 0) { SNDERR("Invalid type for %s", id); return -EINVAL; } continue; } if (strcmp(id, "file") == 0) { err = snd_config_get_string(n, &fname); if (err < 0) { err = snd_config_get_integer(n, &fd); if (err < 0) { SNDERR("Invalid type for %s", id); return -EINVAL; } } continue; } if (strcmp(id, "infile") == 0) { err = snd_config_get_string(n, &ifname); if (err < 0) { err = snd_config_get_integer(n, &ifd); if (err < 0) { SNDERR("Invalid type for %s", id); return -EINVAL; } } continue; } if (strcmp(id, "perm") == 0) { char *str; char *endp; err = snd_config_get_ascii(n, &str); if (err < 0) { SNDERR("The field perm must be a valid file permission"); return err; } if (isdigit(*str) == 0) { SNDERR("The field perm must be a valid file permission"); free(str); return -EINVAL; } perm = strtol(str, &endp, 8); free(str); continue; } SNDERR("Unknown field %s", id); return -EINVAL; }