xref: /third_party/alsa-lib/src/conf.c (revision d5ac70f0)
1/**
2 * \file conf.c
3 * \ingroup Configuration
4 * \brief Configuration helper functions
5 * \author Abramo Bagnara <abramo@alsa-project.org>
6 * \author Jaroslav Kysela <perex@perex.cz>
7 * \date 2000-2001
8 *
9 * Tree based, full nesting configuration functions.
10 *
11 * See the \ref conf page for more details.
12 */
13/*
14 *  Configuration helper functions
15 *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>,
16 *			  Jaroslav Kysela <perex@perex.cz>
17 *
18 *
19 *   This library is free software; you can redistribute it and/or modify
20 *   it under the terms of the GNU Lesser General Public License as
21 *   published by the Free Software Foundation; either version 2.1 of
22 *   the License, or (at your option) any later version.
23 *
24 *   This program is distributed in the hope that it will be useful,
25 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
26 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 *   GNU Lesser General Public License for more details.
28 *
29 *   You should have received a copy of the GNU Lesser General Public
30 *   License along with this library; if not, write to the Free Software
31 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
32 *
33 */
34
35/*! \page conf Configuration files
36
37<P>Configuration files use a simple format allowing modern
38data description like nesting and array assignments.</P>
39
40\section conf_whitespace Whitespace
41
42Whitespace is the collective name given to spaces (blanks), horizontal and
43vertical tabs, newline characters, and comments. Whitespace can
44indicate where configuration tokens start and end, but beyond this function,
45any surplus whitespace is discarded. For example, the two sequences
46
47\code
48  a 1 b 2
49\endcode
50
51and
52
53\code
54  a 1
55     b 2
56\endcode
57
58are lexically equivalent and parse identically to give the four tokens:
59
60\code
61a
621
63b
642
65\endcode
66
67The ASCII characters representing whitespace can occur within literal
68strings, in which case they are protected from the normal parsing process
69(they remain as part of the string). For example:
70
71\code
72  name "John Smith"
73\endcode
74
75parses to two tokens, including the single literal-string token "John
76Smith".
77
78\section conf_linesplicing Line continuation with \
79
80A special case occurs if a newline character in a string is preceded
81by a backslash (\). The backslash and the new line are both discarded,
82allowing two physical lines of text to be treated as one unit.
83
84\code
85"John \
86Smith"
87\endcode
88
89is parsed as "John Smith".
90
91\section conf_comments Comments
92
93A single-line comment begins with the character #. The comment can start
94at any position, and extends to the end of the line.
95
96\code
97  a 1  # this is a comment
98\endcode
99
100\section conf_include Including configuration files
101
102To include another configuration file, write the file name in angle brackets.
103The prefix \c confdir: will reference the global configuration directory.
104
105\code
106</etc/alsa1.conf>
107<confdir:pcm/surround.conf>
108\endcode
109
110\section conf_punctuators Punctuators
111
112The configuration punctuators (also known as separators) are:
113
114\code
115  {} [] , ; = . ' " new-line form-feed carriage-return whitespace
116\endcode
117
118\subsection conf_braces Braces
119
120Opening and closing braces { } indicate the start and end of a compound
121statement:
122
123\code
124a {
125  b 1
126}
127\endcode
128
129\subsection conf_brackets Brackets
130
131Opening and closing brackets indicate a single array definition. The
132identifiers are automatically generated starting with zero.
133
134\code
135a [
136  "first"
137  "second"
138]
139\endcode
140
141The above code is equal to
142
143\code
144a.0 "first"
145a.1 "second"
146\endcode
147
148\subsection conf_comma_semicolon Comma and semicolon
149
150The comma (,) or semicolon (;) can separate value assignments. It is not
151strictly required to use these separators because whitespace suffices to
152separate tokens.
153
154\code
155a 1;
156b 1,
157\endcode
158
159\subsection conf_equal Equal sign
160
161The equal sign (=) can separate variable declarations from
162initialization lists:
163
164\code
165a=1
166b=2
167\endcode
168
169Using equal signs is not required because whitespace suffices to separate
170tokens.
171
172\section conf_assigns Assignments
173
174The configuration file defines id (key) and value pairs. The id (key) can be
175composed from ASCII digits, characters from a to z and A to Z, and the
176underscore (_). The value can be either a string, an integer, a real number,
177or a compound statement.
178
179\subsection conf_single Single assignments
180
181\code
182a 1	# is equal to
183a=1	# is equal to
184a=1;	# is equal to
185a 1,
186\endcode
187
188\subsection conf_compound Compound assignments (definitions using braces)
189
190\code
191a {
192  b = 1
193}
194a={
195  b 1,
196}
197\endcode
198
199\section conf_compound1 Compound assignments (one key definitions)
200
201\code
202a.b 1
203a.b=1
204\endcode
205
206\subsection conf_array Array assignments (definitions using brackets)
207
208\code
209a [
210  "first"
211  "second"
212]
213\endcode
214
215\subsection conf_array1 Array assignments (one key definitions)
216
217\code
218a.0 "first"
219a.1 "second"
220\endcode
221
222\section conf_mode Operation modes for parsing nodes
223
224By default, the node operation mode is 'merge+create', i.e., if
225a configuration node is not present a new one is created, otherwise
226the latest assignment is merged (if possible - type checking). The
227'merge+create' operation mode is specified with the prefix character plus (+).
228
229The operation mode 'merge' merges the node with the old one (which must
230exist). Type checking is done, so strings cannot be assigned to integers
231and so on. This mode is specified with the prefix character minus (-).
232
233The operation mode 'do not override' ignores a new configuration node
234if a configuration node with the same name exists. This mode is specified with
235the prefix character question mark (?).
236
237The operation mode 'override' always overrides the old configuration node
238with new contents. This mode is specified with the prefix character
239exclamation mark (!).
240
241\code
242defaults.pcm.!device 1
243\endcode
244
245\section conf_syntax_summary Syntax summary
246
247\code
248# Configuration file syntax
249
250# Include a new configuration file
251<filename>
252
253# Simple assignment
254name [=] value [,|;]
255
256# Compound assignment (first style)
257name [=] {
258        name1 [=] value [,|;]
259        ...
260}
261
262# Compound assignment (second style)
263name.name1 [=] value [,|;]
264
265# Array assignment (first style)
266name [
267        value0 [,|;]
268        value1 [,|;]
269        ...
270]
271
272# Array assignment (second style)
273name.0 [=] value0 [,|;]
274name.1 [=] value1 [,|;]
275\endcode
276
277\section conf_syntax_ref References
278
279\ref confarg
280\ref conffunc
281\ref confhooks
282
283*/
284
285/*! \page confarg Runtime arguments in configuration files
286
287<P>The ALSA library can accept runtime arguments for some configuration
288blocks. This extension is built on top of the basic configuration file
289syntax.<P>
290
291\section confarg_define Defining arguments
292
293Arguments are defined using the id (key) \c \@args and array values containing
294the string names of the arguments:
295
296\code
297@args [ CARD ]	# or
298@args.0 CARD
299\endcode
300
301\section confarg_type Defining argument types and default values
302
303An argument's type is specified with the id (key) \c \@args and the argument
304name. The type and the default value are specified in the compound block:
305
306\code
307@args.CARD {
308  type string
309  default "abcd"
310}
311\endcode
312
313\section confarg_refer Referring to arguments
314
315Arguments are referred to with a dollar-sign ($) and the name of the argument:
316
317\code
318  card $CARD
319\endcode
320
321\section confarg_math simple math expressions
322
323The simple math expressions are identified using a unix shell like expression syntax
324with a dollar-sign ($) and bracket ([):
325
326\code
327  card "$[$CARD + 1]"
328\endcode
329
330\section confarg_usage Usage
331
332To use a block with arguments, write the argument values after the key,
333separated with a colon (:). For example, all these names for PCM interfaces
334give the same result:
335
336\code
337hw:0,1
338hw:CARD=0,DEV=1
339hw:{CARD 0 DEV 1}
340plug:"hw:0,1"
341plug:{SLAVE="hw:{CARD 0 DEV 1}"}
342\endcode
343
344As you see, arguments can be specified in their proper order or by name.
345Note that arguments enclosed in braces are parsed in the same way as in
346configuration files, but using the override method by default.
347
348\section confarg_example Example
349
350\code
351pcm.demo {
352	@args [ CARD DEVICE ]
353	@args.CARD {
354		type string
355		default "supersonic"
356	}
357	@args.DEVICE {
358		type integer
359		default 0
360	}
361	type hw
362	card $CARD
363	device $DEVICE
364}
365\endcode
366
367
368*/
369
370/*! \page conffunc Runtime functions in configuration files
371
372<P>The ALSA library can modify the configuration at runtime.
373Several built-in functions are available.</P>
374
375<P>A function is defined with the id \c \@func and the function name. All other
376values in the current compound are used as configuration for the function.
377If the compound func.\<function_name\> is defined in the root node, then the
378library and function from this compound configuration are used, otherwise
379'snd_func_' is prefixed to the string and code from the ALSA library is used.
380The definition of a function looks like:</P>
381
382\code
383func.remove_first_char {
384	lib "/usr/lib/libasoundextend.so"
385	func "extend_remove_first_char"
386}
387\endcode
388
389*/
390
391/*! \page confhooks Hooks in configuration files
392
393<P>The hook extension in the ALSA library allows expansion of configuration
394nodes at run-time. The existence of a hook is determined by the
395presence of a \@hooks compound node.</P>
396
397<P>This example defines a hook which loads two configuration files at the
398beginning:</P>
399
400\code
401@hooks [
402	{
403		func load
404		files [
405			"/etc/asound.conf"
406			"~/.asoundrc"
407		]
408		errors false
409	}
410]
411\endcode
412
413\section confhooks_ref Function reference
414
415<UL>
416  <LI>The function load - \c snd_config_hook_load() - loads and parses the
417      given configuration files.
418  <LI>The function load_for_all_cards - \c snd_config_hook_load_for_all_cards() -
419      loads and parses the given configuration files for each installed sound
420      card. The driver name (the type of the sound card) is passed in the
421      private configuration node.
422</UL>
423
424*/
425
426
427#include "local.h"
428#include <stdarg.h>
429#include <stdbool.h>
430#include <limits.h>
431#include <sys/stat.h>
432#include <dirent.h>
433#include <locale.h>
434#ifdef HAVE_LIBPTHREAD
435#include <pthread.h>
436#endif
437
438#ifndef DOC_HIDDEN
439
440#ifdef HAVE_LIBPTHREAD
441static pthread_mutex_t snd_config_update_mutex;
442static pthread_once_t snd_config_update_mutex_once = PTHREAD_ONCE_INIT;
443#endif
444
445struct _snd_config {
446	char *id;
447	snd_config_type_t type;
448	int refcount; /* default = 0 */
449	union {
450		long integer;
451		long long integer64;
452		char *string;
453		double real;
454		const void *ptr;
455		struct {
456			struct list_head fields;
457			bool join;
458		} compound;
459	} u;
460	struct list_head list;
461	snd_config_t *parent;
462	int hop;
463};
464
465struct filedesc {
466	char *name;
467	snd_input_t *in;
468	unsigned int line, column;
469	struct filedesc *next;
470
471	/* list of the include paths (configuration directories),
472	 * defined by <searchdir:relative-path/to/top-alsa-conf-dir>,
473	 * for searching its included files.
474	 */
475	struct list_head include_paths;
476};
477
478/* path to search included files */
479struct include_path {
480	char *dir;
481	struct list_head list;
482};
483
484#define LOCAL_ERROR			(-0x68000000)
485
486#define LOCAL_UNTERMINATED_STRING 	(LOCAL_ERROR - 0)
487#define LOCAL_UNTERMINATED_QUOTE	(LOCAL_ERROR - 1)
488#define LOCAL_UNEXPECTED_CHAR		(LOCAL_ERROR - 2)
489#define LOCAL_UNEXPECTED_EOF		(LOCAL_ERROR - 3)
490
491typedef struct {
492	struct filedesc *current;
493	int unget;
494	int ch;
495} input_t;
496
497#ifdef HAVE_LIBPTHREAD
498
499static void snd_config_init_mutex(void)
500{
501	pthread_mutexattr_t attr;
502
503	pthread_mutexattr_init(&attr);
504#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
505	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
506#endif
507	pthread_mutex_init(&snd_config_update_mutex, &attr);
508	pthread_mutexattr_destroy(&attr);
509}
510
511static inline void snd_config_lock(void)
512{
513	pthread_once(&snd_config_update_mutex_once, snd_config_init_mutex);
514	pthread_mutex_lock(&snd_config_update_mutex);
515}
516
517static inline void snd_config_unlock(void)
518{
519	pthread_mutex_unlock(&snd_config_update_mutex);
520}
521
522#else
523
524static inline void snd_config_lock(void) { }
525static inline void snd_config_unlock(void) { }
526
527#endif
528
529/*
530 * Add a directory to the paths to search included files.
531 * param fd -  File object that owns these paths to search files included by it.
532 * param dir - Path of the directory to add. Allocated externally and need to
533*              be freed manually later.
534 * return - Zero if successful, otherwise a negative error code.
535 *
536 * The direcotry should be a subdiretory of top configuration directory
537 * "/usr/share/alsa/".
538 */
539static int add_include_path(struct filedesc *fd, const char *dir)
540{
541	struct include_path *path;
542	struct filedesc *fd1;
543	struct list_head *pos;
544
545	/* check, if dir is already registered (also in parents) */
546	for (fd1 = fd; fd1; fd1 = fd1->next) {
547		list_for_each(pos, &fd1->include_paths) {
548			path = list_entry(pos, struct include_path, list);
549			if (strcmp(path->dir, dir) == 0)
550				return 0;
551		}
552	}
553
554	path = calloc(1, sizeof(*path));
555	if (!path)
556		return -ENOMEM;
557
558	path->dir = strdup(dir);
559	if (path->dir == NULL) {
560		free(path);
561		return -ENOMEM;
562	}
563
564	list_add_tail(&path->list, &fd->include_paths);
565	return 0;
566}
567
568/*
569 * Free all include paths of a file descriptor.
570 * param fd - File object that owns these paths to search files included by it.
571 */
572static void free_include_paths(struct filedesc *fd)
573{
574	struct list_head *pos, *npos, *base;
575	struct include_path *path;
576
577	base = &fd->include_paths;
578	list_for_each_safe(pos, npos, base) {
579		path = list_entry(pos, struct include_path, list);
580		list_del(&path->list);
581		if (path->dir)
582			free(path->dir);
583		free(path);
584	}
585}
586
587#endif /* DOC_HIDDEN */
588
589/**
590 * \brief Returns the default top-level config directory
591 * \return The top-level config directory path string
592 *
593 * This function returns the string of the top-level config directory path.
594 * If the path is specified via the environment variable \c ALSA_CONFIG_DIR
595 * and the value is a valid path, it returns this value.  If unspecified, it
596 * returns the default value, "/usr/share/alsa".
597 */
598const char *snd_config_topdir(void)
599{
600	static char *topdir;
601
602	if (!topdir) {
603		topdir = getenv("ALSA_CONFIG_DIR");
604		if (!topdir || *topdir != '/' || strlen(topdir) >= PATH_MAX)
605			topdir = ALSA_CONFIG_DIR;
606	}
607	return topdir;
608}
609
610#ifndef DOC_HIDDEN
611
612static char *_snd_config_path(const char *name)
613{
614	const char *root = snd_config_topdir();
615	char *path = malloc(strlen(root) + strlen(name) + 2);
616	if (!path)
617		return NULL;
618	sprintf(path, "%s/%s", root, name);
619	return path;
620}
621
622/*
623 * Search and open a file, and creates a new input object reading from the file.
624 * param inputp - The functions puts the pointer to the new input object
625 *               at the address specified by \p inputp.
626 * param file - Name of the configuration file.
627 * param include_paths - Optional, addtional directories to search the file.
628 * return - Zero if successful, otherwise a negative error code.
629 *
630 * This function will search and open the file in the following order
631 * of priority:
632 * 1. directly open the file by its name (only if absolute)
633 * 2. search for the file name in in additional configuration directories
634 *    specified by users, via alsaconf syntax
635 *    <searchdir:relative-path/to/user/share/alsa>;
636 *    These directories should be subdirectories of /usr/share/alsa.
637 */
638static int input_stdio_open(snd_input_t **inputp, const char *file,
639			    struct filedesc *current)
640{
641	struct list_head *pos;
642	struct include_path *path;
643	char full_path[PATH_MAX];
644	int err;
645
646	if (file[0] == '/')
647		return snd_input_stdio_open(inputp, file, "r");
648
649	/* search file in user specified include paths. These directories
650	 * are subdirectories of /usr/share/alsa.
651	 */
652	err = -ENOENT;
653	while (current) {
654		list_for_each(pos, &current->include_paths) {
655			path = list_entry(pos, struct include_path, list);
656			if (!path->dir)
657				continue;
658
659			snprintf(full_path, PATH_MAX, "%s/%s", path->dir, file);
660			err = snd_input_stdio_open(inputp, full_path, "r");
661			if (err == 0)
662				return 0;
663		}
664		current = current->next;
665	}
666
667	return err;
668}
669
670int _snd_safe_strtoll_base(const char *str, long long *val, int base)
671{
672	char *end;
673	long v;
674	if (!*str)
675		return -EINVAL;
676	errno = 0;
677	v = strtoll(str, &end, base);
678	if (errno)
679		return -errno;
680	if (*end)
681		return -EINVAL;
682	*val = v;
683	return 0;
684}
685
686int _snd_safe_strtol_base(const char *str, long *val, int base)
687{
688	char *end;
689	long v;
690	if (!*str)
691		return -EINVAL;
692	errno = 0;
693	v = strtol(str, &end, base);
694	if (errno)
695		return -errno;
696	if (*end)
697		return -EINVAL;
698	*val = v;
699	return 0;
700}
701
702int _snd_safe_strtod(const char *str, double *val)
703{
704	char *end;
705	double v;
706#ifdef HAVE_USELOCALE
707	locale_t saved_locale, c_locale;
708#else
709	char *saved_locale;
710	char locstr[64]; /* enough? */
711#endif
712	int err;
713
714	if (!*str)
715		return -EINVAL;
716#ifdef HAVE_USELOCALE
717	c_locale = newlocale(LC_NUMERIC_MASK, "C", 0);
718	saved_locale = uselocale(c_locale);
719#else
720	saved_locale = setlocale(LC_NUMERIC, NULL);
721	if (saved_locale) {
722		snprintf(locstr, sizeof(locstr), "%s", saved_locale);
723		setlocale(LC_NUMERIC, "C");
724	}
725#endif
726	errno = 0;
727	v = strtod(str, &end);
728	err = -errno;
729#ifdef HAVE_USELOCALE
730	if (c_locale != (locale_t)0) {
731		uselocale(saved_locale);
732		freelocale(c_locale);
733	}
734#else
735	if (saved_locale)
736		setlocale(LC_NUMERIC, locstr);
737#endif
738	if (err)
739		return err;
740	if (*end)
741		return -EINVAL;
742	*val = v;
743	return 0;
744}
745
746static int get_char(input_t *input)
747{
748	int c;
749	struct filedesc *fd;
750	if (input->unget) {
751		input->unget = 0;
752		return input->ch;
753	}
754 again:
755	fd = input->current;
756	c = snd_input_getc(fd->in);
757	switch (c) {
758	case '\n':
759		fd->column = 0;
760		fd->line++;
761		break;
762	case '\t':
763		fd->column += 8 - fd->column % 8;
764		break;
765	case EOF:
766		if (fd->next) {
767			snd_input_close(fd->in);
768			free(fd->name);
769			input->current = fd->next;
770			free(fd);
771			goto again;
772		}
773		return LOCAL_UNEXPECTED_EOF;
774	default:
775		fd->column++;
776		break;
777	}
778	return (unsigned char)c;
779}
780
781static void unget_char(int c, input_t *input)
782{
783	assert(!input->unget);
784	input->ch = c;
785	input->unget = 1;
786}
787
788static int get_delimstring(char **string, int delim, input_t *input);
789
790static int get_char_skip_comments(input_t *input)
791{
792	int c;
793	while (1) {
794		c = get_char(input);
795		if (c == '<') {
796			char *str;
797			snd_input_t *in;
798			struct filedesc *fd;
799			DIR *dirp;
800			int err = get_delimstring(&str, '>', input);
801			if (err < 0)
802				return err;
803
804			if (!strncmp(str, "searchdir:", 10)) {
805				/* directory to search included files */
806				char *tmp = _snd_config_path(str + 10);
807				free(str);
808				if (tmp == NULL)
809					return -ENOMEM;
810				str = tmp;
811
812				dirp = opendir(str);
813				if (!dirp) {
814					SNDERR("Invalid search dir %s", str);
815					free(str);
816					return -EINVAL;
817				}
818				closedir(dirp);
819
820				err = add_include_path(input->current, str);
821				if (err < 0) {
822					SNDERR("Cannot add search dir %s", str);
823					free(str);
824					return err;
825				}
826				free(str);
827				continue;
828			}
829
830			if (!strncmp(str, "confdir:", 8)) {
831				/* file in the specified directory */
832				char *tmp = _snd_config_path(str + 8);
833				free(str);
834				if (tmp == NULL)
835					return -ENOMEM;
836				str = tmp;
837				err = snd_input_stdio_open(&in, str, "r");
838			} else { /* absolute or relative file path */
839				err = input_stdio_open(&in, str, input->current);
840			}
841
842			if (err < 0) {
843				SNDERR("Cannot access file %s", str);
844				free(str);
845				return err;
846			}
847			fd = malloc(sizeof(*fd));
848			if (!fd) {
849				free(str);
850				return -ENOMEM;
851			}
852			fd->name = str;
853			fd->in = in;
854			fd->next = input->current;
855			fd->line = 1;
856			fd->column = 0;
857			INIT_LIST_HEAD(&fd->include_paths);
858			input->current = fd;
859			continue;
860		}
861		if (c != '#')
862			break;
863		while (1) {
864			c = get_char(input);
865			if (c < 0)
866				return c;
867			if (c == '\n')
868				break;
869		}
870	}
871
872	return c;
873}
874
875
876static int get_nonwhite(input_t *input)
877{
878	int c;
879	while (1) {
880		c = get_char_skip_comments(input);
881		switch (c) {
882		case ' ':
883		case '\f':
884		case '\t':
885		case '\n':
886		case '\r':
887			break;
888		default:
889			return c;
890		}
891	}
892}
893
894static inline int get_hexachar(input_t *input)
895{
896	int c, num = 0;
897
898	c = get_char(input);
899	if (c >= '0' && c <= '9') num |= (c - '0') << 4;
900	else if (c >= 'a' && c <= 'f') num |= (c - 'a') << 4;
901	else if (c >= 'A' && c <= 'F') num |= (c - 'A') << 4;
902	c = get_char(input);
903	if (c >= '0' && c <= '9') num |= (c - '0') << 0;
904	else if (c >= 'a' && c <= 'f') num |= (c - 'a') << 0;
905	else if (c >= 'A' && c <= 'F') num |= (c - 'A') << 0;
906	return num;
907}
908
909static int get_quotedchar(input_t *input)
910{
911	int c;
912	c = get_char(input);
913	switch (c) {
914	case 'n':
915		return '\n';
916	case 't':
917		return '\t';
918	case 'v':
919		return '\v';
920	case 'b':
921		return '\b';
922	case 'r':
923		return '\r';
924	case 'f':
925		return '\f';
926	case 'x':
927		return get_hexachar(input);
928	case '0': case '1': case '2': case '3':
929	case '4': case '5': case '6': case '7':
930	{
931		int num = c - '0';
932		int i = 1;
933		do {
934			c = get_char(input);
935			if (c < '0' || c > '7') {
936				unget_char(c, input);
937				break;
938			}
939			num = num * 8 + c - '0';
940			i++;
941		} while (i < 3);
942		return num;
943	}
944	default:
945		return c;
946	}
947}
948
949#define LOCAL_STR_BUFSIZE	64
950struct local_string {
951	char *buf;
952	size_t alloc;
953	size_t idx;
954	char tmpbuf[LOCAL_STR_BUFSIZE];
955};
956
957static void init_local_string(struct local_string *s)
958{
959	memset(s, 0, sizeof(*s));
960	s->buf = s->tmpbuf;
961	s->alloc = LOCAL_STR_BUFSIZE;
962}
963
964static void free_local_string(struct local_string *s)
965{
966	if (s->buf != s->tmpbuf)
967		free(s->buf);
968}
969
970static int add_char_local_string(struct local_string *s, int c)
971{
972	if (s->idx >= s->alloc) {
973		size_t nalloc = s->alloc * 2;
974		if (s->buf == s->tmpbuf) {
975			s->buf = malloc(nalloc);
976			if (s->buf == NULL)
977				return -ENOMEM;
978			memcpy(s->buf, s->tmpbuf, s->alloc);
979		} else {
980			char *ptr = realloc(s->buf, nalloc);
981			if (ptr == NULL)
982				return -ENOMEM;
983			s->buf = ptr;
984		}
985		s->alloc = nalloc;
986	}
987	s->buf[s->idx++] = c;
988	return 0;
989}
990
991static char *copy_local_string(struct local_string *s)
992{
993	char *dst = malloc(s->idx + 1);
994	if (dst) {
995		memcpy(dst, s->buf, s->idx);
996		dst[s->idx] = '\0';
997	}
998	return dst;
999}
1000
1001static int get_freestring(char **string, int id, input_t *input)
1002{
1003	struct local_string str;
1004	int c;
1005
1006	init_local_string(&str);
1007	while (1) {
1008		c = get_char(input);
1009		if (c < 0) {
1010			if (c == LOCAL_UNEXPECTED_EOF) {
1011				*string = copy_local_string(&str);
1012				if (! *string)
1013					c = -ENOMEM;
1014				else
1015					c = 0;
1016			}
1017			break;
1018		}
1019		switch (c) {
1020		case '.':
1021			if (!id)
1022				break;
1023			/* fall through */
1024		case ' ':
1025		case '\f':
1026		case '\t':
1027		case '\n':
1028		case '\r':
1029		case '=':
1030		case ',':
1031		case ';':
1032		case '{':
1033		case '}':
1034		case '[':
1035		case ']':
1036		case '\'':
1037		case '"':
1038		case '\\':
1039		case '#':
1040			*string = copy_local_string(&str);
1041			if (! *string)
1042				c = -ENOMEM;
1043			else {
1044				unget_char(c, input);
1045				c = 0;
1046			}
1047			goto _out;
1048		default:
1049			break;
1050		}
1051		if (add_char_local_string(&str, c) < 0) {
1052			c = -ENOMEM;
1053			break;
1054		}
1055	}
1056 _out:
1057	free_local_string(&str);
1058	return c;
1059}
1060
1061static int get_delimstring(char **string, int delim, input_t *input)
1062{
1063	struct local_string str;
1064	int c;
1065
1066	init_local_string(&str);
1067	while (1) {
1068		c = get_char(input);
1069		if (c < 0)
1070			break;
1071		if (c == '\\') {
1072			c = get_quotedchar(input);
1073			if (c < 0)
1074				break;
1075			if (c == '\n')
1076				continue;
1077		} else if (c == delim) {
1078			*string = copy_local_string(&str);
1079			if (! *string)
1080				c = -ENOMEM;
1081			else
1082				c = 0;
1083			break;
1084		}
1085		if (add_char_local_string(&str, c) < 0) {
1086			c = -ENOMEM;
1087			break;
1088		}
1089	}
1090	 free_local_string(&str);
1091	 return c;
1092}
1093
1094/* Return 0 for free string, 1 for delimited string */
1095static int get_string(char **string, int id, input_t *input)
1096{
1097	int c = get_nonwhite(input), err;
1098	if (c < 0)
1099		return c;
1100	switch (c) {
1101	case '=':
1102	case ',':
1103	case ';':
1104	case '.':
1105	case '{':
1106	case '}':
1107	case '[':
1108	case ']':
1109	case '\\':
1110		return LOCAL_UNEXPECTED_CHAR;
1111	case '\'':
1112	case '"':
1113		err = get_delimstring(string, c, input);
1114		if (err < 0)
1115			return err;
1116		return 1;
1117	default:
1118		unget_char(c, input);
1119		err = get_freestring(string, id, input);
1120		if (err < 0)
1121			return err;
1122		return 0;
1123	}
1124}
1125
1126static int _snd_config_make(snd_config_t **config, char **id, snd_config_type_t type)
1127{
1128	snd_config_t *n;
1129	assert(config);
1130	n = calloc(1, sizeof(*n));
1131	if (n == NULL) {
1132		if (*id) {
1133			free(*id);
1134			*id = NULL;
1135		}
1136		return -ENOMEM;
1137	}
1138	if (id) {
1139		n->id = *id;
1140		*id = NULL;
1141	}
1142	n->type = type;
1143	if (type == SND_CONFIG_TYPE_COMPOUND)
1144		INIT_LIST_HEAD(&n->u.compound.fields);
1145	*config = n;
1146	return 0;
1147}
1148
1149
1150static int _snd_config_make_add(snd_config_t **config, char **id,
1151				snd_config_type_t type, snd_config_t *parent)
1152{
1153	snd_config_t *n;
1154	int err;
1155	assert(parent->type == SND_CONFIG_TYPE_COMPOUND);
1156	err = _snd_config_make(&n, id, type);
1157	if (err < 0)
1158		return err;
1159	n->parent = parent;
1160	list_add_tail(&n->list, &parent->u.compound.fields);
1161	*config = n;
1162	return 0;
1163}
1164
1165static int _snd_config_search(snd_config_t *config,
1166			      const char *id, int len, snd_config_t **result)
1167{
1168	snd_config_iterator_t i, next;
1169	snd_config_for_each(i, next, config) {
1170		snd_config_t *n = snd_config_iterator_entry(i);
1171		if (len < 0) {
1172			if (strcmp(n->id, id) != 0)
1173				continue;
1174		} else if (strlen(n->id) != (size_t) len ||
1175			   memcmp(n->id, id, (size_t) len) != 0)
1176				continue;
1177		if (result)
1178			*result = n;
1179		return 0;
1180	}
1181	return -ENOENT;
1182}
1183
1184static int parse_value(snd_config_t **_n, snd_config_t *parent, input_t *input, char **id, int skip)
1185{
1186	snd_config_t *n = *_n;
1187	char *s;
1188	int err;
1189
1190	err = get_string(&s, 0, input);
1191	if (err < 0)
1192		return err;
1193	if (skip) {
1194		free(s);
1195		return 0;
1196	}
1197	if (err == 0 && ((s[0] >= '0' && s[0] <= '9') || s[0] == '-')) {
1198		long long i;
1199		errno = 0;
1200		err = safe_strtoll(s, &i);
1201		if (err < 0) {
1202			double r;
1203			err = safe_strtod(s, &r);
1204			if (err >= 0) {
1205				free(s);
1206				if (n) {
1207					if (n->type != SND_CONFIG_TYPE_REAL) {
1208						SNDERR("%s is not a real", *id);
1209						return -EINVAL;
1210					}
1211				} else {
1212					err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_REAL, parent);
1213					if (err < 0)
1214						return err;
1215				}
1216				n->u.real = r;
1217				*_n = n;
1218				return 0;
1219			}
1220		} else {
1221			free(s);
1222			if (n) {
1223				if (n->type != SND_CONFIG_TYPE_INTEGER && n->type != SND_CONFIG_TYPE_INTEGER64) {
1224					SNDERR("%s is not an integer", *id);
1225					return -EINVAL;
1226				}
1227			} else {
1228				if (i <= INT_MAX)
1229					err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, parent);
1230				else
1231					err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER64, parent);
1232				if (err < 0)
1233					return err;
1234			}
1235			if (n->type == SND_CONFIG_TYPE_INTEGER)
1236				n->u.integer = (long) i;
1237			else
1238				n->u.integer64 = i;
1239			*_n = n;
1240			return 0;
1241		}
1242	}
1243	if (n) {
1244		if (n->type != SND_CONFIG_TYPE_STRING) {
1245			SNDERR("%s is not a string", *id);
1246			free(s);
1247			return -EINVAL;
1248		}
1249	} else {
1250		err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_STRING, parent);
1251		if (err < 0)
1252			return err;
1253	}
1254	free(n->u.string);
1255	n->u.string = s;
1256	*_n = n;
1257	return 0;
1258}
1259
1260static int parse_defs(snd_config_t *parent, input_t *input, int skip, int override);
1261static int parse_array_defs(snd_config_t *farther, input_t *input, int skip, int override);
1262
1263static int parse_array_def(snd_config_t *parent, input_t *input, int *idx, int skip, int override)
1264{
1265	char *id = NULL;
1266	int c;
1267	int err;
1268	snd_config_t *n = NULL;
1269
1270	if (!skip) {
1271		snd_config_t *g;
1272		char static_id[12];
1273		while (1) {
1274			snprintf(static_id, sizeof(static_id), "%i", *idx);
1275			if (_snd_config_search(parent, static_id, -1, &g) == 0) {
1276				if (override) {
1277					snd_config_delete(n);
1278				} else {
1279					/* merge */
1280					(*idx)++;
1281					continue;
1282				}
1283			}
1284			break;
1285		}
1286		id = strdup(static_id);
1287		if (id == NULL)
1288			return -ENOMEM;
1289	}
1290	c = get_nonwhite(input);
1291	if (c < 0) {
1292		err = c;
1293		goto __end;
1294	}
1295	switch (c) {
1296	case '{':
1297	case '[':
1298	{
1299		char endchr;
1300		if (!skip) {
1301			if (n) {
1302				if (n->type != SND_CONFIG_TYPE_COMPOUND) {
1303					SNDERR("%s is not a compound", id);
1304					err = -EINVAL;
1305					goto __end;
1306				}
1307			} else {
1308				err = _snd_config_make_add(&n, &id, SND_CONFIG_TYPE_COMPOUND, parent);
1309				if (err < 0)
1310					goto __end;
1311			}
1312		}
1313		if (c == '{') {
1314			err = parse_defs(n, input, skip, override);
1315			endchr = '}';
1316		} else {
1317			err = parse_array_defs(n, input, skip, override);
1318			endchr = ']';
1319		}
1320		c = get_nonwhite(input);
1321		if (c < 0) {
1322			err = c;
1323			goto __end;
1324		}
1325		if (c != endchr) {
1326			if (n)
1327				snd_config_delete(n);
1328			err = LOCAL_UNEXPECTED_CHAR;
1329			goto __end;
1330		}
1331		break;
1332	}
1333	default:
1334		unget_char(c, input);
1335		err = parse_value(&n, parent, input, &id, skip);
1336		if (err < 0)
1337			goto __end;
1338		break;
1339	}
1340	err = 0;
1341      __end:
1342	free(id);
1343      	return err;
1344}
1345
1346static int parse_array_defs(snd_config_t *parent, input_t *input, int skip, int override)
1347{
1348	int idx = 0;
1349	while (1) {
1350		int c = get_nonwhite(input), err;
1351		if (c < 0)
1352			return c;
1353		unget_char(c, input);
1354		if (c == ']')
1355			return 0;
1356		err = parse_array_def(parent, input, &idx, skip, override);
1357		if (err < 0)
1358			return err;
1359		idx++;
1360	}
1361	return 0;
1362}
1363
1364static int parse_def(snd_config_t *parent, input_t *input, int skip, int override)
1365{
1366	char *id = NULL;
1367	int c;
1368	int err;
1369	snd_config_t *n;
1370	enum {MERGE_CREATE, MERGE, OVERRIDE, DONT_OVERRIDE} mode;
1371	while (1) {
1372		c = get_nonwhite(input);
1373		if (c < 0)
1374			return c;
1375		switch (c) {
1376		case '+':
1377			mode = MERGE_CREATE;
1378			break;
1379		case '-':
1380			mode = MERGE;
1381			break;
1382		case '?':
1383			mode = DONT_OVERRIDE;
1384			break;
1385		case '!':
1386			mode = OVERRIDE;
1387			break;
1388		default:
1389			mode = !override ? MERGE_CREATE : OVERRIDE;
1390			unget_char(c, input);
1391		}
1392		err = get_string(&id, 1, input);
1393		if (err < 0)
1394			return err;
1395		c = get_nonwhite(input);
1396		if (c != '.')
1397			break;
1398		if (skip) {
1399			free(id);
1400			continue;
1401		}
1402		if (_snd_config_search(parent, id, -1, &n) == 0) {
1403			if (mode == DONT_OVERRIDE) {
1404				skip = 1;
1405				free(id);
1406				continue;
1407			}
1408			if (mode != OVERRIDE) {
1409				if (n->type != SND_CONFIG_TYPE_COMPOUND) {
1410					SNDERR("%s is not a compound", id);
1411					return -EINVAL;
1412				}
1413				n->u.compound.join = true;
1414				parent = n;
1415				free(id);
1416				continue;
1417			}
1418			snd_config_delete(n);
1419		}
1420		if (mode == MERGE) {
1421			SNDERR("%s does not exists", id);
1422			err = -ENOENT;
1423			goto __end;
1424		}
1425		err = _snd_config_make_add(&n, &id, SND_CONFIG_TYPE_COMPOUND, parent);
1426		if (err < 0)
1427			goto __end;
1428		n->u.compound.join = true;
1429		parent = n;
1430	}
1431	if (c == '=') {
1432		c = get_nonwhite(input);
1433		if (c < 0)
1434			return c;
1435	}
1436	if (!skip) {
1437		if (_snd_config_search(parent, id, -1, &n) == 0) {
1438			if (mode == DONT_OVERRIDE) {
1439				skip = 1;
1440				n = NULL;
1441			} else if (mode == OVERRIDE) {
1442				snd_config_delete(n);
1443				n = NULL;
1444			}
1445		} else {
1446			n = NULL;
1447			if (mode == MERGE) {
1448				SNDERR("%s does not exists", id);
1449				err = -ENOENT;
1450				goto __end;
1451			}
1452		}
1453	}
1454	switch (c) {
1455	case '{':
1456	case '[':
1457	{
1458		char endchr;
1459		if (!skip) {
1460			if (n) {
1461				if (n->type != SND_CONFIG_TYPE_COMPOUND) {
1462					SNDERR("%s is not a compound", id);
1463					err = -EINVAL;
1464					goto __end;
1465				}
1466			} else {
1467				err = _snd_config_make_add(&n, &id, SND_CONFIG_TYPE_COMPOUND, parent);
1468				if (err < 0)
1469					goto __end;
1470			}
1471		}
1472		if (c == '{') {
1473			err = parse_defs(n, input, skip, override);
1474			endchr = '}';
1475		} else {
1476			err = parse_array_defs(n, input, skip, override);
1477			endchr = ']';
1478		}
1479		c = get_nonwhite(input);
1480		if (c != endchr) {
1481			if (n)
1482				snd_config_delete(n);
1483			err = LOCAL_UNEXPECTED_CHAR;
1484			goto __end;
1485		}
1486		break;
1487	}
1488	default:
1489		unget_char(c, input);
1490		err = parse_value(&n, parent, input, &id, skip);
1491		if (err < 0)
1492			goto __end;
1493		break;
1494	}
1495	c = get_nonwhite(input);
1496	switch (c) {
1497	case ';':
1498	case ',':
1499		break;
1500	default:
1501		unget_char(c, input);
1502	}
1503      __end:
1504	free(id);
1505	return err;
1506}
1507
1508static int parse_defs(snd_config_t *parent, input_t *input, int skip, int override)
1509{
1510	int c, err;
1511	while (1) {
1512		c = get_nonwhite(input);
1513		if (c < 0)
1514			return c == LOCAL_UNEXPECTED_EOF ? 0 : c;
1515		unget_char(c, input);
1516		if (c == '}')
1517			return 0;
1518		err = parse_def(parent, input, skip, override);
1519		if (err < 0)
1520			return err;
1521	}
1522	return 0;
1523}
1524
1525static void string_print(char *str, int id, snd_output_t *out)
1526{
1527	int q;
1528	unsigned char *p = (unsigned char *)str;
1529	if (!p || !*p) {
1530		snd_output_puts(out, "''");
1531		return;
1532	}
1533	if (!id) {
1534		switch (*p) {
1535		case '0': case '1': case '2': case '3': case '4':
1536		case '5': case '6': case '7': case '8': case '9':
1537		case '-':
1538			goto quoted;
1539		}
1540	}
1541 loop:
1542	switch (*p) {
1543	case 0:
1544		goto nonquoted;
1545	case ' ':
1546	case '=':
1547	case ';':
1548	case ',':
1549	case '.':
1550	case '{':
1551	case '}':
1552	case '[':
1553	case ']':
1554	case '\'':
1555	case '"':
1556	case '*':
1557	case '#':
1558		goto quoted;
1559	default:
1560		if (*p <= 31 || *p >= 127)
1561			goto quoted;
1562		p++;
1563		goto loop;
1564	}
1565 nonquoted:
1566	snd_output_puts(out, str);
1567	return;
1568 quoted:
1569	q = strchr(str, '\'') ? '"' : '\'';
1570	snd_output_putc(out, q);
1571	p = (unsigned char *)str;
1572	while (*p) {
1573		int c;
1574		c = *p;
1575		switch (c) {
1576		case '\n':
1577			snd_output_putc(out, '\\');
1578			snd_output_putc(out, 'n');
1579			break;
1580		case '\t':
1581			snd_output_putc(out, '\\');
1582			snd_output_putc(out, 't');
1583			break;
1584		case '\v':
1585			snd_output_putc(out, '\\');
1586			snd_output_putc(out, 'v');
1587			break;
1588		case '\b':
1589			snd_output_putc(out, '\\');
1590			snd_output_putc(out, 'b');
1591			break;
1592		case '\r':
1593			snd_output_putc(out, '\\');
1594			snd_output_putc(out, 'r');
1595			break;
1596		case '\f':
1597			snd_output_putc(out, '\\');
1598			snd_output_putc(out, 'f');
1599			break;
1600		default:
1601			if (c == q) {
1602				snd_output_putc(out, '\\');
1603				snd_output_putc(out, c);
1604			} else {
1605				if (c >= 32 && c <= 126)
1606					snd_output_putc(out, c);
1607				else
1608					snd_output_printf(out, "\\%04o", c);
1609			}
1610			break;
1611		}
1612		p++;
1613	}
1614	snd_output_putc(out, q);
1615}
1616
1617static void level_print(snd_output_t *out, unsigned int level)
1618{
1619	char a[level + 1];
1620	memset(a, '\t', level);
1621	a[level] = '\0';
1622	snd_output_puts(out, a);
1623}
1624
1625static int _snd_config_save_children(snd_config_t *config, snd_output_t *out,
1626				     unsigned int level, unsigned int joins,
1627				     int array);
1628
1629int _snd_config_save_node_value(snd_config_t *n, snd_output_t *out,
1630				unsigned int level)
1631{
1632	int err, array;
1633	switch (n->type) {
1634	case SND_CONFIG_TYPE_INTEGER:
1635		snd_output_printf(out, "%ld", n->u.integer);
1636		break;
1637	case SND_CONFIG_TYPE_INTEGER64:
1638		snd_output_printf(out, "%lld", n->u.integer64);
1639		break;
1640	case SND_CONFIG_TYPE_REAL:
1641		snd_output_printf(out, "%-16g", n->u.real);
1642		break;
1643	case SND_CONFIG_TYPE_STRING:
1644		string_print(n->u.string, 0, out);
1645		break;
1646	case SND_CONFIG_TYPE_POINTER:
1647		SNDERR("cannot save runtime pointer type");
1648		return -EINVAL;
1649	case SND_CONFIG_TYPE_COMPOUND:
1650		array = snd_config_is_array(n);
1651		snd_output_putc(out, array ? '[' : '{');
1652		snd_output_putc(out, '\n');
1653		err = _snd_config_save_children(n, out, level + 1, 0, array);
1654		if (err < 0)
1655			return err;
1656		level_print(out, level);
1657		snd_output_putc(out, array ? ']' : '}');
1658		break;
1659	}
1660	return 0;
1661}
1662
1663static void id_print(snd_config_t *n, snd_output_t *out, unsigned int joins)
1664{
1665	if (joins > 0) {
1666		assert(n->parent);
1667		id_print(n->parent, out, joins - 1);
1668		snd_output_putc(out, '.');
1669	}
1670	string_print(n->id, 1, out);
1671}
1672
1673static int _snd_config_save_children(snd_config_t *config, snd_output_t *out,
1674				     unsigned int level, unsigned int joins,
1675				     int array)
1676{
1677	int err;
1678	snd_config_iterator_t i, next;
1679	assert(config && out);
1680	snd_config_for_each(i, next, config) {
1681		snd_config_t *n = snd_config_iterator_entry(i);
1682		if (n->type == SND_CONFIG_TYPE_COMPOUND &&
1683		    n->u.compound.join) {
1684			err = _snd_config_save_children(n, out, level, joins + 1, 0);
1685			if (err < 0)
1686				return err;
1687			continue;
1688		}
1689		level_print(out, level);
1690		if (!array) {
1691			id_print(n, out, joins);
1692			snd_output_putc(out, ' ');
1693#if 0
1694			snd_output_putc(out, '=');
1695#endif
1696		}
1697		err = _snd_config_save_node_value(n, out, level);
1698		if (err < 0)
1699			return err;
1700#if 0
1701		snd_output_putc(out, ';');
1702#endif
1703		snd_output_putc(out, '\n');
1704	}
1705	return 0;
1706}
1707#endif /* DOC_HIDDEN */
1708
1709
1710/**
1711 * \brief Substitutes one configuration node to another.
1712 * \param dst Handle to the destination node.
1713 * \param src Handle to the source node. Must not be the same as \a dst.
1714 * \return Zero if successful, otherwise a negative error code.
1715 *
1716 * If both nodes are compounds, the source compound node members will
1717 * be moved to the destination compound node. The original destination
1718 * compound node members will be deleted (overwritten).
1719 *
1720 * If the destination node is a compound and the source node is
1721 * an ordinary type, the compound members are deleted (including
1722 * their contents).
1723 *
1724 * Otherwise, the source node's value replaces the destination node's
1725 * value.
1726 *
1727 * In any case, a successful call to this function frees the source
1728 * node.
1729 */
1730int snd_config_substitute(snd_config_t *dst, snd_config_t *src)
1731{
1732	assert(dst && src);
1733	if (dst->type == SND_CONFIG_TYPE_COMPOUND) {
1734		int err = snd_config_delete_compound_members(dst);
1735		if (err < 0)
1736			return err;
1737	}
1738	if (dst->type == SND_CONFIG_TYPE_COMPOUND &&
1739	    src->type == SND_CONFIG_TYPE_COMPOUND) {	/* overwrite */
1740		snd_config_iterator_t i, next;
1741		snd_config_for_each(i, next, src) {
1742			snd_config_t *n = snd_config_iterator_entry(i);
1743			n->parent = dst;
1744		}
1745		src->u.compound.fields.next->prev = &dst->u.compound.fields;
1746		src->u.compound.fields.prev->next = &dst->u.compound.fields;
1747	}
1748	free(dst->id);
1749	if (dst->type == SND_CONFIG_TYPE_STRING)
1750		free(dst->u.string);
1751	dst->id = src->id;
1752	dst->type = src->type;
1753	dst->u = src->u;
1754	free(src);
1755	return 0;
1756}
1757
1758/**
1759 * \brief Converts an ASCII string to a configuration node type.
1760 * \param[in] ascii A string containing a configuration node type.
1761 * \param[out] type The node type corresponding to \a ascii.
1762 * \return Zero if successful, otherwise a negative error code.
1763 *
1764 * This function recognizes at least the following node types:
1765 * <dl>
1766 * <dt>integer<dt>#SND_CONFIG_TYPE_INTEGER
1767 * <dt>integer64<dt>#SND_CONFIG_TYPE_INTEGER64
1768 * <dt>real<dt>#SND_CONFIG_TYPE_REAL
1769 * <dt>string<dt>#SND_CONFIG_TYPE_STRING
1770 * <dt>compound<dt>#SND_CONFIG_TYPE_COMPOUND
1771 * </dl>
1772 *
1773 * \par Errors:
1774 * <dl>
1775 * <dt>-EINVAL<dd>Unknown note type in \a type.
1776 * </dl>
1777 */
1778int snd_config_get_type_ascii(const char *ascii, snd_config_type_t *type)
1779{
1780	assert(ascii && type);
1781	if (!strcmp(ascii, "integer")) {
1782		*type = SND_CONFIG_TYPE_INTEGER;
1783		return 0;
1784	}
1785	if (!strcmp(ascii, "integer64")) {
1786		*type = SND_CONFIG_TYPE_INTEGER64;
1787		return 0;
1788	}
1789	if (!strcmp(ascii, "real")) {
1790		*type = SND_CONFIG_TYPE_REAL;
1791		return 0;
1792	}
1793	if (!strcmp(ascii, "string")) {
1794		*type = SND_CONFIG_TYPE_STRING;
1795		return 0;
1796	}
1797	if (!strcmp(ascii, "compound")) {
1798		*type = SND_CONFIG_TYPE_COMPOUND;
1799		return 0;
1800	}
1801	return -EINVAL;
1802}
1803
1804/**
1805 * \brief Returns the type of a configuration node.
1806 * \param config Handle to the configuration node.
1807 * \return The node's type.
1808 *
1809 * \par Conforming to:
1810 * LSB 3.2
1811 */
1812snd_config_type_t snd_config_get_type(const snd_config_t *config)
1813{
1814	return config->type;
1815}
1816
1817static int check_array_item(const char *id, int index)
1818{
1819	const char *p;
1820	long val;
1821
1822	for (p = id; *p; p++) {
1823		if (*p < '0' || *p > '9')
1824			return 0;
1825	}
1826
1827	if (safe_strtol(id, &val))
1828		return 0;
1829	return val == index;
1830}
1831
1832/**
1833 * \brief Returns if the compound is an array (and count of items).
1834 * \param config Handle to the configuration node.
1835 * \return A count of items in array, zero when the compound is not an array,
1836 *         otherwise a negative error code.
1837 */
1838int snd_config_is_array(const snd_config_t *config)
1839{
1840	int idx;
1841	snd_config_iterator_t i, next;
1842	snd_config_t *node;
1843
1844	assert(config);
1845	if (config->type != SND_CONFIG_TYPE_COMPOUND)
1846		return -EINVAL;
1847	idx = 0;
1848	snd_config_for_each(i, next, config) {
1849		node = snd_config_iterator_entry(i);
1850		if (!check_array_item(node->id, idx))
1851			return 0;
1852		idx++;
1853	}
1854	return idx;
1855}
1856
1857/**
1858 * \brief Returns if the compound has no fields (is empty).
1859 * \param config Handle to the configuration node.
1860 * \return A positive value when true, zero when false, otherwise a negative error code.
1861 */
1862int snd_config_is_empty(const snd_config_t *config)
1863{
1864	assert(config);
1865	if (config->type != SND_CONFIG_TYPE_COMPOUND)
1866		return -EINVAL;
1867	return list_empty(&config->u.compound.fields);
1868}
1869
1870/**
1871 * \brief Returns the id of a configuration node.
1872 * \param[in] config Handle to the configuration node.
1873 * \param[out] id The function puts the pointer to the id string at the
1874 *                address specified by \a id.
1875 * \return Zero if successful, otherwise a negative error code.
1876 *
1877 * The returned string is owned by the configuration node; the application
1878 * must not modify or delete it, and the string becomes invalid when the
1879 * node's id changes or when the node is freed.
1880 *
1881 * If the node does not have an id, \a *id is set to \c NULL.
1882 *
1883 * \par Conforming to:
1884 * LSB 3.2
1885 */
1886int snd_config_get_id(const snd_config_t *config, const char **id)
1887{
1888	assert(config && id);
1889	*id = config->id;
1890	return 0;
1891}
1892
1893/**
1894 * \brief Sets the id of a configuration node.
1895 * \param config Handle to the configuration node.
1896 * \param id The new node id, must not be \c NULL.
1897 * \return Zero if successful, otherwise a negative error code.
1898 *
1899 * This function stores a copy of \a id in the node.
1900 *
1901 * \par Errors:
1902 * <dl>
1903 * <dt>-EEXIST<dd>One of \a config's siblings already has the id \a id.
1904 * <dt>-EINVAL<dd>The id of a node with a parent cannot be set to \c NULL.
1905 * <dt>-ENOMEM<dd>Out of memory.
1906 * </dl>
1907 */
1908int snd_config_set_id(snd_config_t *config, const char *id)
1909{
1910	snd_config_iterator_t i, next;
1911	char *new_id;
1912	assert(config);
1913	if (id) {
1914		if (config->parent) {
1915			snd_config_for_each(i, next, config->parent) {
1916				snd_config_t *n = snd_config_iterator_entry(i);
1917				if (n != config && strcmp(id, n->id) == 0)
1918					return -EEXIST;
1919			}
1920		}
1921		new_id = strdup(id);
1922		if (!new_id)
1923			return -ENOMEM;
1924	} else {
1925		if (config->parent)
1926			return -EINVAL;
1927		new_id = NULL;
1928	}
1929	free(config->id);
1930	config->id = new_id;
1931	return 0;
1932}
1933
1934/**
1935 * \brief Creates a top level configuration node.
1936 * \param[out] config Handle to the new node.
1937 * \return Zero if successful, otherwise a negative error code.
1938 *
1939 * The returned node is an empty compound node without a parent and
1940 * without an id.
1941 *
1942 * \par Errors:
1943 * <dl>
1944 * <dt>-ENOMEM<dd>Out of memory.
1945 * </dl>
1946 *
1947 * \par Conforming to:
1948 * LSB 3.2
1949 */
1950int snd_config_top(snd_config_t **config)
1951{
1952	assert(config);
1953	return _snd_config_make(config, 0, SND_CONFIG_TYPE_COMPOUND);
1954}
1955
1956#ifndef DOC_HIDDEN
1957int _snd_config_load_with_include(snd_config_t *config, snd_input_t *in,
1958				  int override, const char * const *include_paths)
1959{
1960	int err;
1961	input_t input;
1962	struct filedesc *fd, *fd_next;
1963
1964	assert(config && in);
1965	fd = malloc(sizeof(*fd));
1966	if (!fd)
1967		return -ENOMEM;
1968	fd->name = NULL;
1969	fd->in = in;
1970	fd->line = 1;
1971	fd->column = 0;
1972	fd->next = NULL;
1973	INIT_LIST_HEAD(&fd->include_paths);
1974	if (include_paths) {
1975		for (; *include_paths; include_paths++) {
1976			err = add_include_path(fd, *include_paths);
1977			if (err < 0)
1978				goto _end;
1979		}
1980	} else {
1981		err = add_include_path(fd, snd_config_topdir());
1982		if (err < 0)
1983			goto _end;
1984	}
1985	input.current = fd;
1986	input.unget = 0;
1987	err = parse_defs(config, &input, 0, override);
1988	fd = input.current;
1989	if (err < 0) {
1990		const char *str;
1991		switch (err) {
1992		case LOCAL_UNTERMINATED_STRING:
1993			str = "Unterminated string";
1994			err = -EINVAL;
1995			break;
1996		case LOCAL_UNTERMINATED_QUOTE:
1997			str = "Unterminated quote";
1998			err = -EINVAL;
1999			break;
2000		case LOCAL_UNEXPECTED_CHAR:
2001			str = "Unexpected char";
2002			err = -EINVAL;
2003			break;
2004		case LOCAL_UNEXPECTED_EOF:
2005			str = "Unexpected end of file";
2006			err = -EINVAL;
2007			break;
2008		default:
2009			str = strerror(-err);
2010			break;
2011		}
2012		SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_", fd->line, fd->column, str);
2013		goto _end;
2014	}
2015	err = get_char(&input);
2016	fd = input.current;
2017	if (err != LOCAL_UNEXPECTED_EOF) {
2018		SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", fd->line, fd->column);
2019		err = -EINVAL;
2020		goto _end;
2021	}
2022	err = 0;
2023 _end:
2024	while (fd->next) {
2025		fd_next = fd->next;
2026		snd_input_close(fd->in);
2027		free(fd->name);
2028		free_include_paths(fd);
2029		free(fd);
2030		fd = fd_next;
2031	}
2032
2033	free_include_paths(fd);
2034	free(fd);
2035	return err;
2036}
2037#endif
2038
2039/**
2040 * \brief Loads a configuration tree.
2041 * \param config Handle to a top level configuration node.
2042 * \param in Input handle to read the configuration from.
2043 * \return Zero if successful, otherwise a negative error code.
2044 *
2045 * The definitions loaded from the input are added to \a config, which
2046 * must be a compound node.
2047 *
2048 * \par Errors:
2049 * Any errors encountered when parsing the input or returned by hooks or
2050 * functions.
2051 *
2052 * \par Conforming to:
2053 * LSB 3.2
2054 */
2055int snd_config_load(snd_config_t *config, snd_input_t *in)
2056{
2057	return _snd_config_load_with_include(config, in, 0, NULL);
2058}
2059
2060/**
2061 * \brief Loads a configuration tree from a string.
2062 * \param[out] config The function puts the handle to the configuration
2063 *	       node loaded from the file(s) at the address specified
2064 *             by \a config.
2065 * \param[in] s String with the ASCII configuration
2066 * \param[in] size String size, if zero, a C string is expected (with termination)
2067 * \return Zero if successful, otherwise a negative error code.
2068 *
2069 * The definitions loaded from the string are put to \a config, which
2070 * is created as a new top node.
2071 *
2072 * \par Errors:
2073 * Any errors encountered when parsing the input or returned by hooks or
2074 * functions.
2075 */
2076int snd_config_load_string(snd_config_t **config, const char *s, size_t size)
2077{
2078	snd_input_t *input;
2079	snd_config_t *dst;
2080	int err;
2081
2082	assert(config && s);
2083	if (size == 0)
2084		size = strlen(s);
2085	err = snd_input_buffer_open(&input, s, size);
2086	if (err < 0)
2087		return err;
2088	err = snd_config_top(&dst);
2089	if (err < 0) {
2090		snd_input_close(input);
2091		return err;
2092	}
2093	err = snd_config_load(dst, input);
2094	snd_input_close(input);
2095	if (err < 0) {
2096		snd_config_delete(dst);
2097		return err;
2098	}
2099	*config = dst;
2100	return 0;
2101}
2102
2103/**
2104 * \brief Loads a configuration tree and overrides existing configuration nodes.
2105 * \param config Handle to a top level configuration node.
2106 * \param in Input handle to read the configuration from.
2107 * \return Zero if successful, otherwise a negative error code.
2108 *
2109 * This function loads definitions from \a in into \a config like
2110 * #snd_config_load, but the default mode for input nodes is 'override'
2111 * (!) instead of 'merge+create' (+).
2112 */
2113int snd_config_load_override(snd_config_t *config, snd_input_t *in)
2114{
2115	return _snd_config_load_with_include(config, in, 1, NULL);
2116}
2117
2118/**
2119 * \brief Adds a child to a compound configuration node.
2120 * \param parent Handle to a compound configuration node.
2121 * \param child Handle to the configuration node to be added.
2122 * \return Zero if successful, otherwise a negative error code.
2123 *
2124 * This function makes the node \a child a child of the node \a parent.
2125 *
2126 * The parent node then owns the child node, i.e., the child node gets
2127 * deleted together with its parent.
2128 *
2129 * \a child must have an id.
2130 *
2131 * \par Errors:
2132 * <dl>
2133 * <dt>-EINVAL<dd>\a child does not have an id.
2134 * <dt>-EINVAL<dd>\a child already has a parent.
2135 * <dt>-EEXIST<dd>\a parent already contains a child node with the same
2136 *                id as \a child.
2137 * </dl>
2138 *
2139 * \par Conforming to:
2140 * LSB 3.2
2141 */
2142int snd_config_add(snd_config_t *parent, snd_config_t *child)
2143{
2144	snd_config_iterator_t i, next;
2145	assert(parent && child);
2146	if (!child->id || child->parent)
2147		return -EINVAL;
2148	snd_config_for_each(i, next, parent) {
2149		snd_config_t *n = snd_config_iterator_entry(i);
2150		if (strcmp(child->id, n->id) == 0)
2151			return -EEXIST;
2152	}
2153	child->parent = parent;
2154	list_add_tail(&child->list, &parent->u.compound.fields);
2155	return 0;
2156}
2157
2158/**
2159 * \brief Adds a child after another child configuration node.
2160 * \param after Handle to the start configuration node.
2161 * \param child Handle to the configuration node to be added.
2162 * \return Zero if successful, otherwise a negative error code.
2163 *
2164 * This function makes the node \a child a child of the parent of
2165 * the node \a after.
2166 *
2167 * The parent node then owns the child node, i.e., the child node gets
2168 * deleted together with its parent.
2169 *
2170 * \a child must have an id.
2171 *
2172 * \par Errors:
2173 * <dl>
2174 * <dt>-EINVAL<dd>\a child does not have an id.
2175 * <dt>-EINVAL<dd>\a child already has a parent.
2176 * <dt>-EEXIST<dd>\a parent already contains a child node with the same
2177 *                id as \a child.
2178 * </dl>
2179 */
2180int snd_config_add_after(snd_config_t *after, snd_config_t *child)
2181{
2182	snd_config_iterator_t i, next;
2183	snd_config_t *parent;
2184	assert(after && child);
2185	parent = after->parent;
2186	assert(parent);
2187	if (!child->id || child->parent)
2188		return -EINVAL;
2189	snd_config_for_each(i, next, parent) {
2190		snd_config_t *n = snd_config_iterator_entry(i);
2191		if (strcmp(child->id, n->id) == 0)
2192			return -EEXIST;
2193	}
2194	child->parent = parent;
2195	list_insert(&child->list, &after->list, after->list.next);
2196	return 0;
2197}
2198
2199/**
2200 * \brief Adds a child before another child configuration node.
2201 * \param before Handle to the start configuration node.
2202 * \param child Handle to the configuration node to be added.
2203 * \return Zero if successful, otherwise a negative error code.
2204 *
2205 * This function makes the node \a child a child of the parent of
2206 * the node \a before.
2207 *
2208 * The parent node then owns the child node, i.e., the child node gets
2209 * deleted together with its parent.
2210 *
2211 * \a child must have an id.
2212 *
2213 * \par Errors:
2214 * <dl>
2215 * <dt>-EINVAL<dd>\a child does not have an id.
2216 * <dt>-EINVAL<dd>\a child already has a parent.
2217 * <dt>-EEXIST<dd>\a parent already contains a child node with the same
2218 *                id as \a child.
2219 * </dl>
2220 */
2221int snd_config_add_before(snd_config_t *before, snd_config_t *child)
2222{
2223	snd_config_iterator_t i, next;
2224	snd_config_t *parent;
2225	assert(before && child);
2226	parent = before->parent;
2227	assert(parent);
2228	if (!child->id || child->parent)
2229		return -EINVAL;
2230	snd_config_for_each(i, next, parent) {
2231		snd_config_t *n = snd_config_iterator_entry(i);
2232		if (strcmp(child->id, n->id) == 0)
2233			return -EEXIST;
2234	}
2235	child->parent = parent;
2236	list_insert(&child->list, before->list.prev, &before->list);
2237	return 0;
2238}
2239
2240/*
2241 * append all src items to the end of dst arrray
2242 */
2243static int _snd_config_array_merge(snd_config_t *dst, snd_config_t *src, int index)
2244{
2245	snd_config_iterator_t si, snext;
2246	int err;
2247
2248	snd_config_for_each(si, snext, src) {
2249		snd_config_t *sn = snd_config_iterator_entry(si);
2250		char id[16];
2251		snd_config_remove(sn);
2252		snprintf(id, sizeof(id), "%d", index++);
2253		err = snd_config_set_id(sn, id);
2254		if (err < 0) {
2255			snd_config_delete(sn);
2256			return err;
2257		}
2258		sn->parent = dst;
2259		list_add_tail(&sn->list, &dst->u.compound.fields);
2260	}
2261	snd_config_delete(src);
2262	return 0;
2263}
2264
2265/**
2266 * \brief In-place merge of two config handles
2267 * \param[out] dst Config handle for the merged contents
2268 * \param[in] src Config handle to merge into dst (may be NULL)
2269 * \param[in] override Override flag
2270 * \return Zero if successful, otherwise a negative error code.
2271 *
2272 * This function merges all fields from the source compound to the destination compound.
2273 * When the \a override flag is set, the related subtree in \a dst is replaced from \a src.
2274 *
2275 * When \a override is not set, the child compounds are traversed and merged.
2276 *
2277 * The configuration elements other than compounds are always substituted (overwritten)
2278 * from the \a src config handle.
2279 *
2280 * The src handle is deleted.
2281 *
2282 * Note: On error, config handles may be modified.
2283 *
2284 * \par Errors:
2285 * <dl>
2286 * <dt>-EEXIST<dd>identifier already exists (!override)
2287 * <dt>-ENOMEM<dd>not enough memory
2288 * </dl>
2289 */
2290int snd_config_merge(snd_config_t *dst, snd_config_t *src, int override)
2291{
2292	snd_config_iterator_t di, si, dnext, snext;
2293	bool found;
2294	int err, array;
2295
2296	assert(dst);
2297	if (src == NULL)
2298		return 0;
2299	if (dst->type != SND_CONFIG_TYPE_COMPOUND || src->type != SND_CONFIG_TYPE_COMPOUND)
2300		return snd_config_substitute(dst, src);
2301	array = snd_config_is_array(dst);
2302	if (array && snd_config_is_array(src))
2303		return _snd_config_array_merge(dst, src, array);
2304	snd_config_for_each(si, snext, src) {
2305		snd_config_t *sn = snd_config_iterator_entry(si);
2306		found = false;
2307		snd_config_for_each(di, dnext, dst) {
2308			snd_config_t *dn = snd_config_iterator_entry(di);
2309			if (strcmp(sn->id, dn->id) == 0) {
2310				if (override ||
2311				    sn->type != SND_CONFIG_TYPE_COMPOUND ||
2312				    dn->type != SND_CONFIG_TYPE_COMPOUND) {
2313					snd_config_remove(sn);
2314					err = snd_config_substitute(dn, sn);
2315					if (err < 0)
2316						return err;
2317				} else {
2318					err = snd_config_merge(dn, sn, 0);
2319					if (err < 0)
2320						return err;
2321				}
2322				found = true;
2323				break;
2324			}
2325		}
2326		if (!found) {
2327			/* move config from src to dst */
2328			snd_config_remove(sn);
2329			sn->parent = dst;
2330			list_add_tail(&sn->list, &dst->u.compound.fields);
2331		}
2332	}
2333	snd_config_delete(src);
2334	return 0;
2335}
2336
2337/**
2338 * \brief Removes a configuration node from its tree.
2339 * \param config Handle to the configuration node to be removed.
2340 * \return Zero if successful, otherwise a negative error code.
2341 *
2342 * This function makes \a config a top-level node, i.e., if \a config
2343 * has a parent, then \a config is removed from the list of the parent's
2344 * children.
2345 *
2346 * This functions does \e not free the removed node.
2347 *
2348 * \sa snd_config_delete
2349 */
2350int snd_config_remove(snd_config_t *config)
2351{
2352	assert(config);
2353	if (config->parent)
2354		list_del(&config->list);
2355	config->parent = NULL;
2356	return 0;
2357}
2358
2359/**
2360 * \brief Frees a configuration node.
2361 * \param config Handle to the configuration node to be deleted.
2362 * \return Zero if successful, otherwise a negative error code.
2363 *
2364 * This function frees a configuration node and all its resources.
2365 *
2366 * If the node is a child node, it is removed from the tree before being
2367 * deleted.
2368 *
2369 * If the node is a compound node, its descendants (the whole subtree)
2370 * are deleted recursively.
2371 *
2372 * The function is supposed to be called only for locally copied config
2373 * trees.  For the global tree, take the reference via #snd_config_update_ref
2374 * and free it via #snd_config_unref.
2375 *
2376 * \par Conforming to:
2377 * LSB 3.2
2378 *
2379 * \sa snd_config_remove
2380 */
2381int snd_config_delete(snd_config_t *config)
2382{
2383	assert(config);
2384	if (config->refcount > 0) {
2385		config->refcount--;
2386		return 0;
2387	}
2388	switch (config->type) {
2389	case SND_CONFIG_TYPE_COMPOUND:
2390	{
2391		int err;
2392		struct list_head *i;
2393		i = config->u.compound.fields.next;
2394		while (i != &config->u.compound.fields) {
2395			struct list_head *nexti = i->next;
2396			snd_config_t *child = snd_config_iterator_entry(i);
2397			err = snd_config_delete(child);
2398			if (err < 0)
2399				return err;
2400			i = nexti;
2401		}
2402		break;
2403	}
2404	case SND_CONFIG_TYPE_STRING:
2405		free(config->u.string);
2406		break;
2407	default:
2408		break;
2409	}
2410	if (config->parent)
2411		list_del(&config->list);
2412	free(config->id);
2413	free(config);
2414	return 0;
2415}
2416
2417/**
2418 * \brief Deletes the children of a node.
2419 * \param config Handle to the compound configuration node.
2420 * \return Zero if successful, otherwise a negative error code.
2421 *
2422 * This function removes and frees all children of a configuration node.
2423 *
2424 * Any compound nodes among the children of \a config are deleted
2425 * recursively.
2426 *
2427 * After a successful call to this function, \a config is an empty
2428 * compound node.
2429 *
2430 * \par Errors:
2431 * <dl>
2432 * <dt>-EINVAL<dd>\a config is not a compound node.
2433 * </dl>
2434 */
2435int snd_config_delete_compound_members(const snd_config_t *config)
2436{
2437	int err;
2438	struct list_head *i;
2439
2440	assert(config);
2441	if (config->type != SND_CONFIG_TYPE_COMPOUND)
2442		return -EINVAL;
2443	i = config->u.compound.fields.next;
2444	while (i != &config->u.compound.fields) {
2445		struct list_head *nexti = i->next;
2446		snd_config_t *child = snd_config_iterator_entry(i);
2447		err = snd_config_delete(child);
2448		if (err < 0)
2449			return err;
2450		i = nexti;
2451	}
2452	return 0;
2453}
2454
2455/**
2456 * \brief Creates a configuration node.
2457 * \param[out] config The function puts the handle to the new node at
2458 *                    the address specified by \a config.
2459 * \param[in] id The id of the new node.
2460 * \param[in] type The type of the new node.
2461 * \return Zero if successful, otherwise a negative error code.
2462 *
2463 * This functions creates a new node of the specified type.
2464 * The new node has id \a id, which may be \c NULL.
2465 *
2466 * The value of the new node is zero (for numbers), or \c NULL (for
2467 * strings and pointers), or empty (for compound nodes).
2468 *
2469 * \par Errors:
2470 * <dl>
2471 * <dt>-ENOMEM<dd>Out of memory.
2472 * </dl>
2473 */
2474int snd_config_make(snd_config_t **config, const char *id,
2475		    snd_config_type_t type)
2476{
2477	char *id1;
2478	assert(config);
2479	if (id) {
2480		id1 = strdup(id);
2481		if (!id1)
2482			return -ENOMEM;
2483	} else
2484		id1 = NULL;
2485	return _snd_config_make(config, &id1, type);
2486}
2487
2488/**
2489 * \brief Creates an integer configuration node.
2490 * \param[out] config The function puts the handle to the new node at
2491 *                    the address specified by \a config.
2492 * \param[in] id The id of the new node.
2493 * \return Zero if successful, otherwise a negative error code.
2494 *
2495 * This function creates a new node of type #SND_CONFIG_TYPE_INTEGER and
2496 * with value \c 0.
2497 *
2498 * \par Errors:
2499 * <dl>
2500 * <dt>-ENOMEM<dd>Out of memory.
2501 * </dl>
2502 *
2503 * \par Conforming to:
2504 * LSB 3.2
2505 *
2506 * \sa snd_config_imake_integer
2507 */
2508int snd_config_make_integer(snd_config_t **config, const char *id)
2509{
2510	return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
2511}
2512
2513/**
2514 * \brief Creates a 64-bit-integer configuration node.
2515 * \param[out] config The function puts the handle to the new node at
2516 *                    the address specified by \a config.
2517 * \param[in] id The id of the new node.
2518 * \return Zero if successful, otherwise a negative error code.
2519 *
2520 * This function creates a new node of type #SND_CONFIG_TYPE_INTEGER64
2521 * and with value \c 0.
2522 *
2523 * \par Errors:
2524 * <dl>
2525 * <dt>-ENOMEM<dd>Out of memory.
2526 * </dl>
2527 *
2528 * \par Conforming to:
2529 * LSB 3.2
2530 *
2531 * \sa snd_config_imake_integer64
2532 */
2533int snd_config_make_integer64(snd_config_t **config, const char *id)
2534{
2535	return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64);
2536}
2537
2538/**
2539 * \brief Creates a real number configuration node.
2540 * \param[out] config The function puts the handle to the new node at
2541 *                    the address specified by \a config.
2542 * \param[in] id The id of the new node.
2543 * \return Zero if successful, otherwise a negative error code.
2544 *
2545 * This function creates a new node of type #SND_CONFIG_TYPE_REAL and
2546 * with value \c 0.0.
2547 *
2548 * \par Errors:
2549 * <dl>
2550 * <dt>-ENOMEM<dd>Out of memory.
2551 * </dl>
2552 *
2553 * \sa snd_config_imake_real
2554 */
2555int snd_config_make_real(snd_config_t **config, const char *id)
2556{
2557	return snd_config_make(config, id, SND_CONFIG_TYPE_REAL);
2558}
2559
2560/**
2561 * \brief Creates a string configuration node.
2562 * \param[out] config The function puts the handle to the new node at
2563 *                    the address specified by \a config.
2564 * \param[in] id The id of the new node.
2565 * \return Zero if successful, otherwise a negative error code.
2566 *
2567 * This function creates a new node of type #SND_CONFIG_TYPE_STRING and
2568 * with value \c NULL.
2569 *
2570 * \par Errors:
2571 * <dl>
2572 * <dt>-ENOMEM<dd>Out of memory.
2573 * </dl>
2574 *
2575 * \par Conforming to:
2576 * LSB 3.2
2577 *
2578 * \sa snd_config_imake_string
2579 */
2580int snd_config_make_string(snd_config_t **config, const char *id)
2581{
2582	return snd_config_make(config, id, SND_CONFIG_TYPE_STRING);
2583}
2584
2585/**
2586 * \brief Creates a pointer configuration node.
2587 * \param[out] config The function puts the handle to the new node at
2588 *                    the address specified by \a config.
2589 * \param[in] id The id of the new node.
2590 * \return Zero if successful, otherwise a negative error code.
2591 *
2592 * This function creates a new node of type #SND_CONFIG_TYPE_POINTER and
2593 * with value \c NULL.
2594 *
2595 * \par Errors:
2596 * <dl>
2597 * <dt>-ENOMEM<dd>Out of memory.
2598 * </dl>
2599 *
2600 * \sa snd_config_imake_pointer
2601 */
2602int snd_config_make_pointer(snd_config_t **config, const char *id)
2603{
2604	return snd_config_make(config, id, SND_CONFIG_TYPE_POINTER);
2605}
2606
2607/**
2608 * \brief Creates an empty compound configuration node.
2609 * \param[out] config The function puts the handle to the new node at
2610 *                    the address specified by \a config.
2611 * \param[in] id The id of the new node.
2612 * \param[in] join Join flag.
2613 * \return Zero if successful, otherwise a negative error code.
2614 *
2615 * This function creates a new empty node of type
2616 * #SND_CONFIG_TYPE_COMPOUND.
2617 *
2618 * \a join determines how the compound node's id is printed when the
2619 * configuration is saved to a text file.  For example, if the join flag
2620 * of compound node \c a is zero, the output will look as follows:
2621 * \code
2622 * a {
2623 *     b "hello"
2624 *     c 42
2625 * }
2626 * \endcode
2627 * If, however, the join flag of \c a is nonzero, its id will be joined
2628 * with its children's ids, like this:
2629 * \code
2630 * a.b "hello"
2631 * a.c 42
2632 * \endcode
2633 * An \e empty compound node with its join flag set would result in no
2634 * output, i.e., after saving and reloading the configuration file, that
2635 * compound node would be lost.
2636 *
2637 * \par Errors:
2638 * <dl>
2639 * <dt>-ENOMEM<dd>Out of memory.
2640 * </dl>
2641 *
2642 * \par Conforming to:
2643 * LSB 3.2
2644 */
2645int snd_config_make_compound(snd_config_t **config, const char *id,
2646			     int join)
2647{
2648	int err;
2649	err = snd_config_make(config, id, SND_CONFIG_TYPE_COMPOUND);
2650	if (err < 0)
2651		return err;
2652	(*config)->u.compound.join = join;
2653	return 0;
2654}
2655
2656/**
2657 * \brief Creates an empty compound configuration node in the path.
2658 * \param[out] config The function puts the handle to the new or
2659 *		      existing compound node at the address specified
2660 *		      by \a config.
2661 * \param[in] root The id of the new node.
2662 * \param[in] key The id of the new node.
2663 * \param[in] join Join flag.
2664 * \param[in] override Override flag.
2665 * \return Zero if successful, otherwise a negative error code.
2666 *
2667 * This function creates a new empty node of type
2668 * #SND_CONFIG_TYPE_COMPOUND if the path does not exist. Otherwise,
2669 * the node from the current configuration tree is returned without
2670 * any modification. The \a join argument is ignored in this case.
2671 *
2672 * \a join determines how the compound node's id is printed when the
2673 * configuration is saved to a text file.  For example, if the join flag
2674 * of compound node \c a is zero, the output will look as follows:
2675 * \code
2676 * a {
2677 *     b "hello"
2678 *     c 42
2679 * }
2680 * \endcode
2681 * If, however, the join flag of \c a is nonzero, its id will be joined
2682 * with its children's ids, like this:
2683 * \code
2684 * a.b "hello"
2685 * a.c 42
2686 * \endcode
2687 * An \e empty compound node with its join flag set would result in no
2688 * output, i.e., after saving and reloading the configuration file, that
2689 * compound node would be lost.
2690 *
2691 * \par Errors:
2692 * <dl>
2693 * <dt>-ENOMEM<dd>Out of memory.
2694 * <dt>-EACCESS<dd>Path exists, but it's not a compound (!override)
2695 * </dl>
2696 */
2697int snd_config_make_path(snd_config_t **config, snd_config_t *root,
2698			 const char *key, int join, int override)
2699{
2700	snd_config_t *n;
2701	const char *p;
2702	int err;
2703
2704	while (1) {
2705		p = strchr(key, '.');
2706		if (p) {
2707			err = _snd_config_search(root, key, p - key, &n);
2708			if (err < 0) {
2709				size_t l = p - key;
2710				char *s = malloc(l + 1);
2711				if (s == NULL)
2712					return -ENOMEM;
2713				strncpy(s, key, l);
2714				s[l] = '\0';
2715				err = snd_config_make_compound(&n, s, join);
2716				free(s);
2717				if (err < 0)
2718					return err;
2719				err = snd_config_add(root, n);
2720				if (err < 0)
2721					return err;
2722			}
2723			root = n;
2724			key = p + 1;
2725		} else {
2726			err = _snd_config_search(root, key, -1, config);
2727			if (err == 0) {
2728				if ((*config)->type != SND_CONFIG_TYPE_COMPOUND) {
2729					if (override) {
2730						err = snd_config_delete(*config);
2731						if (err < 0)
2732							return err;
2733						goto __make;
2734					} else {
2735						return -EACCES;
2736					}
2737				}
2738				return 0;
2739			}
2740__make:
2741			err = snd_config_make_compound(&n, key, join);
2742			if (err < 0)
2743				return err;
2744			err = snd_config_add(root, n);
2745			if (err < 0)
2746				return err;
2747			*config = n;
2748			return 0;
2749		}
2750	}
2751}
2752
2753/**
2754 * \brief Creates an integer configuration node with the given initial value.
2755 * \param[out] config The function puts the handle to the new node at
2756 *                    the address specified by \a config.
2757 * \param[in] id The id of the new node.
2758 * \param[in] value The initial value of the new node.
2759 * \return Zero if successful, otherwise a negative error code.
2760 *
2761 * This function creates a new node of type #SND_CONFIG_TYPE_INTEGER and
2762 * with value \a value.
2763 *
2764 * \par Errors:
2765 * <dl>
2766 * <dt>-ENOMEM<dd>Out of memory.
2767 * </dl>
2768 *
2769 * \par Conforming to:
2770 * LSB 3.2
2771 */
2772int snd_config_imake_integer(snd_config_t **config, const char *id, const long value)
2773{
2774	int err;
2775
2776	err = snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
2777	if (err < 0)
2778		return err;
2779	(*config)->u.integer = value;
2780	return 0;
2781}
2782
2783/**
2784 * \brief Creates a 64-bit-integer configuration node with the given initial value.
2785 * \param[out] config The function puts the handle to the new node at
2786 *                    the address specified by \a config.
2787 * \param[in] id The id of the new node.
2788 * \param[in] value The initial value of the new node.
2789 * \return Zero if successful, otherwise a negative error code.
2790 *
2791 * This function creates a new node of type #SND_CONFIG_TYPE_INTEGER64
2792 * and with value \a value.
2793 *
2794 * \par Errors:
2795 * <dl>
2796 * <dt>-ENOMEM<dd>Out of memory.
2797 * </dl>
2798 *
2799 * \par Conforming to:
2800 * LSB 3.2
2801 */
2802int snd_config_imake_integer64(snd_config_t **config, const char *id, const long long value)
2803{
2804	int err;
2805
2806	err = snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64);
2807	if (err < 0)
2808		return err;
2809	(*config)->u.integer64 = value;
2810	return 0;
2811}
2812
2813/**
2814 * \brief Creates a real number configuration node with the given initial value.
2815 * \param[out] config The function puts the handle to the new node at
2816 *                    the address specified by \a config.
2817 * \param[in] id The id of the new node.
2818 * \param[in] value The initial value of the new node.
2819 * \return Zero if successful, otherwise a negative error code.
2820 *
2821 * This function creates a new node of type #SND_CONFIG_TYPE_REAL and
2822 * with value \a value.
2823 *
2824 * \par Errors:
2825 * <dl>
2826 * <dt>-ENOMEM<dd>Out of memory.
2827 * </dl>
2828 */
2829int snd_config_imake_real(snd_config_t **config, const char *id, const double value)
2830{
2831	int err;
2832
2833	err = snd_config_make(config, id, SND_CONFIG_TYPE_REAL);
2834	if (err < 0)
2835		return err;
2836	(*config)->u.real = value;
2837	return 0;
2838}
2839
2840/**
2841 * \brief Creates a string configuration node with the given initial value.
2842 * \param[out] config The function puts the handle to the new node at
2843 *                    the address specified by \a config.
2844 * \param[in] id The id of the new node.
2845 * \param[in] value The initial value of the new node.  May be \c NULL.
2846 * \return Zero if successful, otherwise a negative error code.
2847 *
2848 * This function creates a new node of type #SND_CONFIG_TYPE_STRING and
2849 * with a copy of the string \c value.
2850 *
2851 * \par Errors:
2852 * <dl>
2853 * <dt>-ENOMEM<dd>Out of memory.
2854 * </dl>
2855 *
2856 * \par Conforming to:
2857 * LSB 3.2
2858 */
2859int snd_config_imake_string(snd_config_t **config, const char *id, const char *value)
2860{
2861	int err;
2862	snd_config_t *tmp;
2863
2864	err = snd_config_make(&tmp, id, SND_CONFIG_TYPE_STRING);
2865	if (err < 0)
2866		return err;
2867	if (value) {
2868		tmp->u.string = strdup(value);
2869		if (!tmp->u.string) {
2870			snd_config_delete(tmp);
2871			return -ENOMEM;
2872		}
2873	} else {
2874		tmp->u.string = NULL;
2875	}
2876	*config = tmp;
2877	return 0;
2878}
2879
2880/**
2881 * \brief Creates a string configuration node with the given initial value.
2882 * \param[out] config The function puts the handle to the new node at
2883 *                    the address specified by \a config.
2884 * \param[in] id The id of the new node.
2885 * \param[in] value The initial value of the new node.  May be \c NULL.
2886 * \return Zero if successful, otherwise a negative error code.
2887 *
2888 * This function creates a new node of type #SND_CONFIG_TYPE_STRING. The node
2889 * contains with a copy of the string \c value, replacing any character other
2890 * than alphanumeric, space, or '-' with the character '_'.
2891 *
2892 * \par Errors:
2893 * <dl>
2894 * <dt>-ENOMEM<dd>Out of memory.
2895 * </dl>
2896 *
2897 * \par Conforming to:
2898 * LSB 3.2
2899 */
2900int snd_config_imake_safe_string(snd_config_t **config, const char *id, const char *value)
2901{
2902	int err;
2903	snd_config_t *tmp;
2904	char *c;
2905
2906	err = snd_config_make(&tmp, id, SND_CONFIG_TYPE_STRING);
2907	if (err < 0)
2908		return err;
2909	if (value) {
2910		tmp->u.string = strdup(value);
2911		if (!tmp->u.string) {
2912			snd_config_delete(tmp);
2913			return -ENOMEM;
2914		}
2915
2916		for (c = tmp->u.string; *c; c++) {
2917			if (*c == ' ' || *c == '-' || *c == '_' ||
2918				(*c >= '0' && *c <= '9') ||
2919				(*c >= 'a' && *c <= 'z') ||
2920				(*c >= 'A' && *c <= 'Z'))
2921					continue;
2922			*c = '_';
2923		}
2924	} else {
2925		tmp->u.string = NULL;
2926	}
2927	*config = tmp;
2928	return 0;
2929}
2930
2931
2932/**
2933 * \brief Creates a pointer configuration node with the given initial value.
2934 * \param[out] config The function puts the handle to the new node at
2935 *                    the address specified by \a config.
2936 * \param[in] id The id of the new node.
2937 * \param[in] value The initial value of the new node.
2938 * \return Zero if successful, otherwise a negative error code.
2939 *
2940 * This function creates a new node of type #SND_CONFIG_TYPE_POINTER and
2941 * with value \c value.
2942 *
2943 * \par Errors:
2944 * <dl>
2945 * <dt>-ENOMEM<dd>Out of memory.
2946 * </dl>
2947 */
2948int snd_config_imake_pointer(snd_config_t **config, const char *id, const void *value)
2949{
2950	int err;
2951
2952	err = snd_config_make(config, id, SND_CONFIG_TYPE_POINTER);
2953	if (err < 0)
2954		return err;
2955	(*config)->u.ptr = value;
2956	return 0;
2957}
2958
2959/**
2960 * \brief Changes the value of an integer configuration node.
2961 * \param config Handle to the configuration node.
2962 * \param value The new value for the node.
2963 * \return Zero if successful, otherwise a negative error code.
2964 *
2965 * \par Errors:
2966 * <dl>
2967 * <dt>-EINVAL<dd>\a config is not an integer node.
2968 * </dl>
2969 *
2970 * \par Conforming to:
2971 * LSB 3.2
2972 */
2973int snd_config_set_integer(snd_config_t *config, long value)
2974{
2975	assert(config);
2976	if (config->type != SND_CONFIG_TYPE_INTEGER)
2977		return -EINVAL;
2978	config->u.integer = value;
2979	return 0;
2980}
2981
2982/**
2983 * \brief Changes the value of a 64-bit-integer configuration node.
2984 * \param config Handle to the configuration node.
2985 * \param value The new value for the node.
2986 * \return Zero if successful, otherwise a negative error code.
2987 *
2988 * \par Errors:
2989 * <dl>
2990 * <dt>-EINVAL<dd>\a config is not a 64-bit-integer node.
2991 * </dl>
2992 *
2993 * \par Conforming to:
2994 * LSB 3.2
2995 */
2996int snd_config_set_integer64(snd_config_t *config, long long value)
2997{
2998	assert(config);
2999	if (config->type != SND_CONFIG_TYPE_INTEGER64)
3000		return -EINVAL;
3001	config->u.integer64 = value;
3002	return 0;
3003}
3004
3005/**
3006 * \brief Changes the value of a real-number configuration node.
3007 * \param config Handle to the configuration node.
3008 * \param value The new value for the node.
3009 * \return Zero if successful, otherwise a negative error code.
3010 *
3011 * \par Errors:
3012 * <dl>
3013 * <dt>-EINVAL<dd>\a config is not a real-number node.
3014 * </dl>
3015 */
3016int snd_config_set_real(snd_config_t *config, double value)
3017{
3018	assert(config);
3019	if (config->type != SND_CONFIG_TYPE_REAL)
3020		return -EINVAL;
3021	config->u.real = value;
3022	return 0;
3023}
3024
3025/**
3026 * \brief Changes the value of a string configuration node.
3027 * \param config Handle to the configuration node.
3028 * \param value The new value for the node.  May be \c NULL.
3029 * \return Zero if successful, otherwise a negative error code.
3030 *
3031 * This function deletes the old string in the node and stores a copy of
3032 * \a value string in the node.
3033 *
3034 * \par Errors:
3035 * <dl>
3036 * <dt>-EINVAL<dd>\a config is not a string node.
3037 * </dl>
3038 *
3039 * \par Conforming to:
3040 * LSB 3.2
3041 */
3042int snd_config_set_string(snd_config_t *config, const char *value)
3043{
3044	char *new_string;
3045	assert(config);
3046	if (config->type != SND_CONFIG_TYPE_STRING)
3047		return -EINVAL;
3048	if (value) {
3049		new_string = strdup(value);
3050		if (!new_string)
3051			return -ENOMEM;
3052	} else {
3053		new_string = NULL;
3054	}
3055	free(config->u.string);
3056	config->u.string = new_string;
3057	return 0;
3058}
3059
3060/**
3061 * \brief Changes the value of a pointer configuration node.
3062 * \param config Handle to the configuration node.
3063 * \param value The new value for the node.  May be \c NULL.
3064 * \return Zero if successful, otherwise a negative error code.
3065 *
3066 * This function does not free the old pointer in the node.
3067 *
3068 * \par Errors:
3069 * <dl>
3070 * <dt>-EINVAL<dd>\a config is not a pointer node.
3071 * </dl>
3072 */
3073int snd_config_set_pointer(snd_config_t *config, const void *value)
3074{
3075	assert(config);
3076	if (config->type != SND_CONFIG_TYPE_POINTER)
3077		return -EINVAL;
3078	config->u.ptr = value;
3079	return 0;
3080}
3081
3082/**
3083 * \brief Changes the value of a configuration node.
3084 * \param config Handle to the configuration node.
3085 * \param ascii The new value for the node, as an ASCII string.
3086 * \return Zero if successful, otherwise a negative error code.
3087 *
3088 * This function changes the node's value to a new value that is parsed
3089 * from the string \a ascii.  \a ascii must not be \c NULL, not even for
3090 * a string node.
3091 *
3092 * The node's type does not change, i.e., the string must contain a
3093 * valid value with the same type as the node's type.  For a string
3094 * node, the node's new value is a copy of \a ascii.
3095 *
3096 * \par Errors:
3097 * <dl>
3098 * <dt>-EINVAL<dd>\a config is not a number or string node.
3099 * <dt>-EINVAL<dd>The value in \a ascii cannot be parsed.
3100 * <dt>-ERANGE<dd>The value in \a ascii is too big for the node's type.
3101 * <dt>-ENOMEM<dd>Out of memory.
3102 * </dl>
3103 *
3104 * \par Conforming to:
3105 * LSB 3.2
3106 */
3107int snd_config_set_ascii(snd_config_t *config, const char *ascii)
3108{
3109	assert(config && ascii);
3110	switch (config->type) {
3111	case SND_CONFIG_TYPE_INTEGER:
3112		{
3113			long i;
3114			int err = safe_strtol(ascii, &i);
3115			if (err < 0)
3116				return err;
3117			config->u.integer = i;
3118		}
3119		break;
3120	case SND_CONFIG_TYPE_INTEGER64:
3121		{
3122			long long i;
3123			int err = safe_strtoll(ascii, &i);
3124			if (err < 0)
3125				return err;
3126			config->u.integer64 = i;
3127		}
3128		break;
3129	case SND_CONFIG_TYPE_REAL:
3130		{
3131			double d;
3132			int err = safe_strtod(ascii, &d);
3133			if (err < 0)
3134				return err;
3135			config->u.real = d;
3136			break;
3137		}
3138	case SND_CONFIG_TYPE_STRING:
3139		{
3140			char *ptr = strdup(ascii);
3141			if (ptr == NULL)
3142				return -ENOMEM;
3143			free(config->u.string);
3144			config->u.string = ptr;
3145		}
3146		break;
3147	default:
3148		return -EINVAL;
3149	}
3150	return 0;
3151}
3152
3153/**
3154 * \brief Returns the value of an integer configuration node.
3155 * \param[in] config Handle to the configuration node.
3156 * \param[out] ptr The node's value.
3157 * \return Zero if successful, otherwise a negative error code.
3158 *
3159 * \par Errors:
3160 * <dl>
3161 * <dt>-EINVAL<dd>\a config is not an integer node.
3162 * </dl>
3163 *
3164 * \par Conforming to:
3165 * LSB 3.2
3166 */
3167int snd_config_get_integer(const snd_config_t *config, long *ptr)
3168{
3169	assert(config && ptr);
3170	if (config->type != SND_CONFIG_TYPE_INTEGER)
3171		return -EINVAL;
3172	*ptr = config->u.integer;
3173	return 0;
3174}
3175
3176/**
3177 * \brief Returns the value of a 64-bit-integer configuration node.
3178 * \param[in] config Handle to the configuration node.
3179 * \param[out] ptr The node's value.
3180 * \return Zero if successful, otherwise a negative error code.
3181 *
3182 * \par Errors:
3183 * <dl>
3184 * <dt>-EINVAL<dd>\a config is not a 64-bit-integer node.
3185 * </dl>
3186 *
3187 * \par Conforming to:
3188 * LSB 3.2
3189 */
3190int snd_config_get_integer64(const snd_config_t *config, long long *ptr)
3191{
3192	assert(config && ptr);
3193	if (config->type != SND_CONFIG_TYPE_INTEGER64)
3194		return -EINVAL;
3195	*ptr = config->u.integer64;
3196	return 0;
3197}
3198
3199/**
3200 * \brief Returns the value of a real-number configuration node.
3201 * \param[in] config Handle to the configuration node.
3202 * \param[out] ptr The node's value.
3203 * \return Zero if successful, otherwise a negative error code.
3204 *
3205 * \par Errors:
3206 * <dl>
3207 * <dt>-EINVAL<dd>\a config is not a real-number node.
3208 * </dl>
3209 */
3210int snd_config_get_real(const snd_config_t *config, double *ptr)
3211{
3212	assert(config && ptr);
3213	if (config->type != SND_CONFIG_TYPE_REAL)
3214		return -EINVAL;
3215	*ptr = config->u.real;
3216	return 0;
3217}
3218
3219/**
3220 * \brief Returns the value of a real or integer configuration node.
3221 * \param[in] config Handle to the configuration node.
3222 * \param[out] ptr The node's value.
3223 * \return Zero if successful, otherwise a negative error code.
3224 *
3225 * If the node's type is integer or integer64, the value is converted
3226 * to the \c double type on the fly.
3227 *
3228 * \par Errors:
3229 * <dl>
3230 * <dt>-EINVAL<dd>\a config is not a number node.
3231 * </dl>
3232 */
3233int snd_config_get_ireal(const snd_config_t *config, double *ptr)
3234{
3235	assert(config && ptr);
3236	if (config->type == SND_CONFIG_TYPE_REAL)
3237		*ptr = config->u.real;
3238	else if (config->type == SND_CONFIG_TYPE_INTEGER)
3239		*ptr = config->u.integer;
3240	else if (config->type == SND_CONFIG_TYPE_INTEGER64)
3241		*ptr = config->u.integer64;
3242	else
3243		return -EINVAL;
3244	return 0;
3245}
3246
3247/**
3248 * \brief Returns the value of a string configuration node.
3249 * \param[in] config Handle to the configuration node.
3250 * \param[out] ptr The function puts the node's value at the address
3251 *                 specified by \a ptr.
3252 * \return Zero if successful, otherwise a negative error code.
3253 *
3254 * The returned string is owned by the configuration node; the
3255 * application must not modify or delete it, and the string becomes
3256 * invalid when the node's value changes or when the node is freed.
3257 *
3258 * The string may be \c NULL.
3259 *
3260 * \par Errors:
3261 * <dl>
3262 * <dt>-EINVAL<dd>\a config is not a string node.
3263 * </dl>
3264 *
3265 * \par Conforming to:
3266 * LSB 3.2
3267 */
3268int snd_config_get_string(const snd_config_t *config, const char **ptr)
3269{
3270	assert(config && ptr);
3271	if (config->type != SND_CONFIG_TYPE_STRING)
3272		return -EINVAL;
3273	*ptr = config->u.string;
3274	return 0;
3275}
3276
3277/**
3278 * \brief Returns the value of a pointer configuration node.
3279 * \param[in] config Handle to the configuration node.
3280 * \param[out] ptr The function puts the node's value at the address
3281 *                 specified by \a ptr.
3282 * \return Zero if successful, otherwise a negative error code.
3283 *
3284 * \par Errors:
3285 * <dl>
3286 * <dt>-EINVAL<dd>\a config is not a string node.
3287 * </dl>
3288 */
3289int snd_config_get_pointer(const snd_config_t *config, const void **ptr)
3290{
3291	assert(config && ptr);
3292	if (config->type != SND_CONFIG_TYPE_POINTER)
3293		return -EINVAL;
3294	*ptr = config->u.ptr;
3295	return 0;
3296}
3297
3298/**
3299 * \brief Returns the value of a configuration node as a string.
3300 * \param[in] config Handle to the configuration node.
3301 * \param[out] ascii The function puts the pointer to the returned
3302 *                   string at the address specified by \a ascii.
3303 * \return Zero if successful, otherwise a negative error code.
3304 *
3305 * This function dynamically allocates the returned string.  The
3306 * application is responsible for deleting it with \c free() when it is
3307 * no longer used.
3308 *
3309 * For a string node with \c NULL value, the returned string is \c NULL.
3310 *
3311 * Supported node types are #SND_CONFIG_TYPE_INTEGER,
3312 * #SND_CONFIG_TYPE_INTEGER64, #SND_CONFIG_TYPE_REAL, and
3313 * #SND_CONFIG_TYPE_STRING.
3314 *
3315 * \par Errors:
3316 * <dl>
3317 * <dt>-EINVAL<dd>\a config is not a (64-bit) integer or real number or
3318 *                string node.
3319 * <dt>-ENOMEM<dd>Out of memory.
3320 * </dl>
3321 *
3322 * \par Conforming to:
3323 * LSB 3.2
3324 */
3325int snd_config_get_ascii(const snd_config_t *config, char **ascii)
3326{
3327	assert(config && ascii);
3328	switch (config->type) {
3329	case SND_CONFIG_TYPE_INTEGER:
3330		{
3331			char res[12];
3332			int err;
3333			err = snprintf(res, sizeof(res), "%li", config->u.integer);
3334			if (err < 0 || err == sizeof(res)) {
3335				assert(0);
3336				return -ENOMEM;
3337			}
3338			*ascii = strdup(res);
3339		}
3340		break;
3341	case SND_CONFIG_TYPE_INTEGER64:
3342		{
3343			char res[32];
3344			int err;
3345			err = snprintf(res, sizeof(res), "%lli", config->u.integer64);
3346			if (err < 0 || err == sizeof(res)) {
3347				assert(0);
3348				return -ENOMEM;
3349			}
3350			*ascii = strdup(res);
3351		}
3352		break;
3353	case SND_CONFIG_TYPE_REAL:
3354		{
3355			char res[32];
3356			int err;
3357			err = snprintf(res, sizeof(res), "%-16g", config->u.real);
3358			if (err < 0 || err == sizeof(res)) {
3359				assert(0);
3360				return -ENOMEM;
3361			}
3362			if (res[0]) {		/* trim the string */
3363				char *ptr;
3364				ptr = res + strlen(res) - 1;
3365				while (ptr != res && *ptr == ' ')
3366					ptr--;
3367				if (*ptr != ' ')
3368					ptr++;
3369				*ptr = '\0';
3370			}
3371			*ascii = strdup(res);
3372		}
3373		break;
3374	case SND_CONFIG_TYPE_STRING:
3375		if (config->u.string)
3376			*ascii = strdup(config->u.string);
3377		else {
3378			*ascii = NULL;
3379			return 0;
3380		}
3381		break;
3382	default:
3383		return -EINVAL;
3384	}
3385	if (*ascii == NULL)
3386		return -ENOMEM;
3387	return 0;
3388}
3389
3390/**
3391 * \brief Compares the id of a configuration node to a given string.
3392 * \param config Handle to the configuration node.
3393 * \param id ASCII id.
3394 * \return The same value as the result of the \c strcmp function, i.e.,
3395 *         less than zero if \a config's id is lexicographically less
3396 *         than \a id, zero if \a config's id is equal to id, greater
3397 *         than zero otherwise.
3398 */
3399int snd_config_test_id(const snd_config_t *config, const char *id)
3400{
3401	assert(config && id);
3402	if (config->id)
3403		return strcmp(config->id, id);
3404	else
3405		return -1;
3406}
3407
3408/**
3409 * \brief Dumps the contents of a configuration node or tree.
3410 * \param config Handle to the (root) configuration node.
3411 * \param out Output handle.
3412 * \return Zero if successful, otherwise a negative error code.
3413 *
3414 * This function writes a textual representation of \a config's value to
3415 * the output \a out.
3416 *
3417 * \par Errors:
3418 * <dl>
3419 * <dt>-EINVAL<dd>A node in the tree has a type that cannot be printed,
3420 *                i.e., #SND_CONFIG_TYPE_POINTER.
3421 * </dl>
3422 *
3423 * \par Conforming to:
3424 * LSB 3.2
3425 */
3426int snd_config_save(snd_config_t *config, snd_output_t *out)
3427{
3428	assert(config && out);
3429	if (config->type == SND_CONFIG_TYPE_COMPOUND) {
3430		int array = snd_config_is_array(config);
3431		return _snd_config_save_children(config, out, 0, 0, array);
3432	} else {
3433		return _snd_config_save_node_value(config, out, 0);
3434	}
3435}
3436
3437/*
3438 *  *** search macros ***
3439 */
3440
3441#ifndef DOC_HIDDEN
3442
3443#define SND_CONFIG_SEARCH(config, key, result, extra_code) \
3444{ \
3445	snd_config_t *n; \
3446	int err; \
3447	const char *p; \
3448	assert(config && key); \
3449	while (1) { \
3450		if (config->type != SND_CONFIG_TYPE_COMPOUND) \
3451			return -ENOENT; \
3452		{ extra_code ; } \
3453		p = strchr(key, '.'); \
3454		if (p) { \
3455			err = _snd_config_search(config, key, p - key, &n); \
3456			if (err < 0) \
3457				return err; \
3458			config = n; \
3459			key = p + 1; \
3460		} else \
3461			return _snd_config_search(config, key, -1, result); \
3462	} \
3463}
3464
3465#define SND_CONFIG_SEARCHA(root, config, key, result, fcn, extra_code) \
3466{ \
3467	snd_config_t *n; \
3468	int err; \
3469	const char *p; \
3470	assert(config && key); \
3471	while (1) { \
3472		if (config->type != SND_CONFIG_TYPE_COMPOUND) { \
3473			if (snd_config_get_string(config, &p) < 0) \
3474				return -ENOENT; \
3475			err = fcn(root, root, p, &config); \
3476			if (err < 0) \
3477				return err; \
3478		} \
3479		{ extra_code ; } \
3480		p = strchr(key, '.'); \
3481		if (p) { \
3482			err = _snd_config_search(config, key, p - key, &n); \
3483			if (err < 0) \
3484				return err; \
3485			config = n; \
3486			key = p + 1; \
3487		} else \
3488			return _snd_config_search(config, key, -1, result); \
3489	} \
3490}
3491
3492#define SND_CONFIG_SEARCHV(config, result, fcn) \
3493{ \
3494	snd_config_t *n; \
3495	va_list arg; \
3496	assert(config); \
3497	va_start(arg, result); \
3498	while (1) { \
3499		const char *k = va_arg(arg, const char *); \
3500		int err; \
3501		if (!k) \
3502			break; \
3503		err = fcn(config, k, &n); \
3504		if (err < 0) { \
3505			va_end(arg); \
3506			return err; \
3507		} \
3508		config = n; \
3509	} \
3510	va_end(arg); \
3511	if (result) \
3512		*result = n; \
3513	return 0; \
3514}
3515
3516#define SND_CONFIG_SEARCHVA(root, config, result, fcn) \
3517{ \
3518	snd_config_t *n; \
3519	va_list arg; \
3520	assert(config); \
3521	va_start(arg, result); \
3522	while (1) { \
3523		const char *k = va_arg(arg, const char *); \
3524		int err; \
3525		if (!k) \
3526			break; \
3527		err = fcn(root, config, k, &n); \
3528		if (err < 0) { \
3529			va_end(arg); \
3530			return err; \
3531		} \
3532		config = n; \
3533	} \
3534	va_end(arg); \
3535	if (result) \
3536		*result = n; \
3537	return 0; \
3538}
3539
3540#define SND_CONFIG_SEARCH_ALIAS(config, base, key, result, fcn1, fcn2) \
3541{ \
3542	snd_config_t *res = NULL; \
3543	char *old_key; \
3544	int err, first = 1, maxloop = 1000; \
3545	assert(config && key); \
3546	while (1) { \
3547		old_key = strdup(key); \
3548		if (old_key == NULL) { \
3549			err = -ENOMEM; \
3550			res = NULL; \
3551			break; \
3552		} \
3553		err = first && base ? -EIO : fcn1(config, config, key, &res); \
3554		if (err < 0) { \
3555			if (!base) \
3556				break; \
3557			err = fcn2(config, config, &res, base, key, NULL); \
3558			if (err < 0) \
3559				break; \
3560		} \
3561		if (snd_config_get_string(res, &key) < 0) \
3562			break; \
3563		assert(key); \
3564		if (!first && (strcmp(key, old_key) == 0 || maxloop <= 0)) { \
3565			if (maxloop == 0) \
3566				SNDERR("maximum loop count reached (circular configuration?)"); \
3567			else \
3568				SNDERR("key %s refers to itself", key); \
3569			err = -EINVAL; \
3570			res = NULL; \
3571			break; \
3572		} \
3573		free(old_key); \
3574		first = 0; \
3575		maxloop--; \
3576	} \
3577	free(old_key); \
3578	if (!res) \
3579		return err; \
3580	if (result) \
3581		*result = res; \
3582	return 0; \
3583}
3584
3585#endif /* DOC_HIDDEN */
3586
3587/**
3588 * \brief Searches for a node in a configuration tree.
3589 * \param[in] config Handle to the root of the configuration (sub)tree to search.
3590 * \param[in] key Search key: one or more node ids, separated with dots.
3591 * \param[out] result When \a result != \c NULL, the function puts the
3592 *                    handle to the node found at the address specified
3593 *                    by \a result.
3594 * \return Zero if successful, otherwise a negative error code.
3595 *
3596 * This function searches for a child node of \a config that is
3597 * identified by \a key, which contains either the id of a direct child
3598 * node of \a config, or a series of ids, separated with dots, where
3599 * each id specifies a node that is contained in the previous compound
3600 * node.
3601 *
3602 * In the following example, the comment after each node shows the
3603 * search key to find that node, assuming that \a config is a handle to
3604 * the compound node with id \c config:
3605 * \code
3606 * config {
3607 *     a 42               # "a"
3608 *     b {                # "b"
3609 *         c "cee"        # "b.c"
3610 *         d {            # "b.d"
3611 *             e 2.71828  # "b.d.e"
3612 *         }
3613 *     }
3614 * }
3615 * \endcode
3616 *
3617 * \par Errors:
3618 * <dl>
3619 * <dt>-ENOENT<dd>An id in \a key does not exist.
3620 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3621 *                not a compound node.
3622 * </dl>
3623 *
3624 * \par Conforming to:
3625 * LSB 3.2
3626 */
3627int snd_config_search(snd_config_t *config, const char *key, snd_config_t **result)
3628{
3629	SND_CONFIG_SEARCH(config, key, result, );
3630}
3631
3632/**
3633 * \brief Searches for a node in a configuration tree, expanding aliases.
3634 * \param[in] root Handle to the root configuration node containing
3635 *                 alias definitions.
3636 * \param[in] config Handle to the root of the configuration (sub)tree to search.
3637 * \param[in] key Search key: one or more node keys, separated with dots.
3638 * \param[out] result When \a result != \c NULL, the function puts the
3639 *                    handle to the node found at the address specified
3640 *                    by \a result.
3641 * \return Zero if successful, otherwise a negative error code.
3642 *
3643 * This functions searches for a child node of \a config like
3644 * #snd_config_search.  However, any compound node can also be
3645 * identified by an alias, which is a string node whose value is taken
3646 * as the id of a compound node below \a root.
3647 *
3648 * \a root must be a compound node.
3649 * \a root and \a config may be the same node.
3650 *
3651 * For example, with the following configuration, the call
3652 * \code
3653 * snd_config_searcha(root, config, "a.b.c.d", &result);
3654 * \endcode
3655 * would return the node with id \c d:
3656 * \code
3657 * config {
3658 *     a {
3659 *         b bb
3660 *     }
3661 * }
3662 * root {
3663 *     bb {
3664 *         c cc
3665 *     }
3666 *     cc ccc
3667 *     ccc {
3668 *         d {
3669 *             x "icks"
3670 *         }
3671 *     }
3672 * }
3673 * \endcode
3674 *
3675 * \par Errors:
3676 * <dl>
3677 * <dt>-ENOENT<dd>An id in \a key or an alias id does not exist.
3678 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3679 *                not a compound or string node.
3680 * </dl>
3681 */
3682int snd_config_searcha(snd_config_t *root, snd_config_t *config, const char *key, snd_config_t **result)
3683{
3684	SND_CONFIG_SEARCHA(root, config, key, result, snd_config_searcha, );
3685}
3686
3687/**
3688 * \brief Searches for a node in a configuration tree.
3689 * \param[in] config Handle to the root of the configuration (sub)tree to search.
3690 * \param[out] result When \a result != \c NULL, the function puts the
3691 *                    handle to the node found at the address specified
3692 *                    by \a result.
3693 * \param[in] ... One or more concatenated dot-separated search keys,
3694 *                terminated with \c NULL.
3695 * \return Zero if successful, otherwise a negative error code.
3696 *
3697 * This functions searches for a child node of \a config like
3698 * #snd_config_search, but the search key is the concatenation of all
3699 * passed search key strings.  For example, the call
3700 * \code
3701 * snd_config_searchv(cfg, &res, "a", "b.c", "d.e", NULL);
3702 * \endcode
3703 * is equivalent to the call
3704 * \code
3705 * snd_config_search(cfg, "a.b.c.d.e", &res);
3706 * \endcode
3707 *
3708 * \par Errors:
3709 * <dl>
3710 * <dt>-ENOENT<dd>An id in a search key does not exist.
3711 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3712 *                not a compound node.
3713 * </dl>
3714 *
3715 * \par Conforming to:
3716 * LSB 3.2
3717 */
3718int snd_config_searchv(snd_config_t *config, snd_config_t **result, ...)
3719{
3720	SND_CONFIG_SEARCHV(config, result, snd_config_search);
3721}
3722
3723/**
3724 * \brief Searches for a node in a configuration tree, expanding aliases.
3725 * \param[in] root Handle to the root configuration node containing
3726 *                 alias definitions.
3727 * \param[in] config Handle to the root of the configuration (sub)tree to search.
3728 * \param[out] result When \a result != \c NULL, the function puts the
3729 *                    handle to the node found at the address specified
3730 *                    by \a result.
3731 * \param[in] ... One or more concatenated dot separated search keys,
3732 *                terminated with \c NULL.
3733 * \return Zero if successful, otherwise a negative error code.
3734 *
3735 * This function searches for a child node of \a config, allowing
3736 * aliases, like #snd_config_searcha, but the search key is the
3737 * concatenation of all passed seach key strings, like with
3738 * #snd_config_searchv.
3739 *
3740 * \par Errors:
3741 * <dl>
3742 * <dt>-ENOENT<dd>An id in a search key does not exist.
3743 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3744 *                not a compound or string node.
3745 * </dl>
3746 */
3747int snd_config_searchva(snd_config_t *root, snd_config_t *config, snd_config_t **result, ...)
3748{
3749	SND_CONFIG_SEARCHVA(root, config, result, snd_config_searcha);
3750}
3751
3752/**
3753 * \brief Searches for a node in a configuration tree, expanding aliases.
3754 * \param[in] config Handle to the root of the configuration (sub)tree to search.
3755 * \param[in] base Search key base, or \c NULL.
3756 * \param[in] key Search key suffix.
3757 * \param[out] result When \a result != \c NULL, the function puts the
3758 *                    handle to the node found at the address specified
3759 *                    by \a result.
3760 * \return Zero if successful, otherwise a negative error code.
3761 *
3762 * This functions searches for a child node of \a config, allowing
3763 * aliases, like #snd_config_searcha.  However, alias definitions are
3764 * searched below \a config (there is no separate \a root parameter),
3765 * and \a base specifies a seach key that identifies a compound node
3766 * that is used to search for an alias definitions that is not found
3767 * directly below \a config and that does not contain a period.  In
3768 * other words, when \c "id" is not found in \a config, this function
3769 * also tries \c "base.id".
3770 *
3771 * \par Errors:
3772 * <dl>
3773 * <dt>-ENOENT<dd>An id in \a key or an alias id does not exist.
3774 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3775 *                not a compound or string node.
3776 * </dl>
3777 */
3778int snd_config_search_alias(snd_config_t *config,
3779			    const char *base, const char *key,
3780			    snd_config_t **result)
3781{
3782	SND_CONFIG_SEARCH_ALIAS(config, base, key, result,
3783				snd_config_searcha, snd_config_searchva);
3784}
3785
3786static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data);
3787
3788/**
3789 * \brief Searches for a node in a configuration tree and expands hooks.
3790 * \param[in,out] config Handle to the root of the configuration
3791 *                       (sub)tree to search.
3792 * \param[in] key Search key: one or more node keys, separated with dots.
3793 * \param[out] result The function puts the handle to the node found at
3794 *                    the address specified by \a result.
3795 * \return Zero if successful, otherwise a negative error code.
3796 *
3797 * This functions searches for a child node of \a config like
3798 * #snd_config_search, but any compound nodes to be searched that
3799 * contain hooks are modified by the respective hook functions.
3800 *
3801 * \par Errors:
3802 * <dl>
3803 * <dt>-ENOENT<dd>An id in \a key does not exist.
3804 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3805 *                not a compound node.
3806 * </dl>
3807 * Additionally, any errors encountered when parsing the hook
3808 * definitions or returned by the hook functions.
3809 */
3810int snd_config_search_hooks(snd_config_t *config, const char *key, snd_config_t **result)
3811{
3812	SND_CONFIG_SEARCH(config, key, result, \
3813					err = snd_config_hooks(config, NULL); \
3814					if (err < 0) \
3815						return err; \
3816			 );
3817}
3818
3819/**
3820 * \brief Searches for a node in a configuration tree, expanding aliases and hooks.
3821 * \param[in] root Handle to the root configuration node containing
3822 *                 alias definitions.
3823 * \param[in,out] config Handle to the root of the configuration
3824 *                       (sub)tree to search.
3825 * \param[in] key Search key: one or more node keys, separated with dots.
3826 * \param[out] result The function puts the handle to the node found at
3827 *                    the address specified by \a result.
3828 * \return Zero if successful, otherwise a negative error code.
3829 *
3830 * This function searches for a child node of \a config, allowing
3831 * aliases, like #snd_config_searcha, and expanding hooks, like
3832 * #snd_config_search_hooks.
3833 *
3834 * \par Errors:
3835 * <dl>
3836 * <dt>-ENOENT<dd>An id in \a key or an alias id does not exist.
3837 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3838 *                not a compound node.
3839 * </dl>
3840 * Additionally, any errors encountered when parsing the hook
3841 * definitions or returned by the hook functions.
3842 */
3843int snd_config_searcha_hooks(snd_config_t *root, snd_config_t *config, const char *key, snd_config_t **result)
3844{
3845	SND_CONFIG_SEARCHA(root, config, key, result,
3846					snd_config_searcha_hooks,
3847					err = snd_config_hooks(config, NULL); \
3848					if (err < 0) \
3849						return err; \
3850			 );
3851}
3852
3853/**
3854 * \brief Searches for a node in a configuration tree, expanding aliases and hooks.
3855 * \param[in] root Handle to the root configuration node containing
3856 *                 alias definitions.
3857 * \param[in,out] config Handle to the root of the configuration
3858 *                       (sub)tree to search.
3859 * \param[out] result The function puts the handle to the node found at
3860 *                    the address specified by \a result.
3861 * \param[in] ... One or more concatenated dot separated search keys,
3862 *                terminated with \c NULL.
3863 * \return Zero if successful, otherwise a negative error code.
3864 *
3865 * This function searches for a child node of \a config, allowing
3866 * aliases and expanding hooks like #snd_config_searcha_hooks, but the
3867 * search key is the concatenation of all passed seach key strings, like
3868 * with #snd_config_searchv.
3869 *
3870 * \par Errors:
3871 * <dl>
3872 * <dt>-ENOENT<dd>An id in \a key or an alias id does not exist.
3873 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3874 *                not a compound node.
3875 * </dl>
3876 * Additionally, any errors encountered when parsing the hook
3877 * definitions or returned by the hook functions.
3878 */
3879int snd_config_searchva_hooks(snd_config_t *root, snd_config_t *config,
3880			      snd_config_t **result, ...)
3881{
3882	SND_CONFIG_SEARCHVA(root, config, result, snd_config_searcha_hooks);
3883}
3884
3885/**
3886 * \brief Searches for a node in a configuration tree, using an alias and expanding hooks.
3887 * \param[in] config Handle to the root of the configuration (sub)tree
3888 *                   to search.
3889 * \param[in] base Search key base, or \c NULL.
3890 * \param[in] key Search key suffix.
3891 * \param[out] result The function puts the handle to the node found at
3892 *                    the address specified by \a result.
3893 * \return Zero if successful, otherwise a negative error code.
3894 *
3895 * This functions searches for a child node of \a config, allowing
3896 * aliases, like #snd_config_search_alias, and expanding hooks, like
3897 * #snd_config_search_hooks.
3898 *
3899 * \par Errors:
3900 * <dl>
3901 * <dt>-ENOENT<dd>An id in \a key or an alias id does not exist.
3902 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
3903 *                not a compound node.
3904 * </dl>
3905 * Additionally, any errors encountered when parsing the hook
3906 * definitions or returned by the hook functions.
3907 */
3908int snd_config_search_alias_hooks(snd_config_t *config,
3909				  const char *base, const char *key,
3910				  snd_config_t **result)
3911{
3912	SND_CONFIG_SEARCH_ALIAS(config, base, key, result,
3913				snd_config_searcha_hooks,
3914				snd_config_searchva_hooks);
3915}
3916
3917/** The name of the environment variable containing the files list for #snd_config_update. */
3918#define ALSA_CONFIG_PATH_VAR "ALSA_CONFIG_PATH"
3919
3920/**
3921 * \brief Configuration top-level node (the global configuration).
3922 *
3923 * This variable contains a handle to the top-level configuration node,
3924 * as loaded from global configuration file.
3925 *
3926 * This variable is initialized or updated by #snd_config_update.
3927 * Functions like #snd_pcm_open (that use a device name from the global
3928 * configuration) automatically call #snd_config_update.  Before the
3929 * first call to #snd_config_update, this variable is \c NULL.
3930 *
3931 * The global configuration files are specified in the environment
3932 * variable \c ALSA_CONFIG_PATH.  If this is not set, the default value
3933 * is "/usr/share/alsa/alsa.conf".
3934 *
3935 * \warning Whenever the configuration tree is updated, all string
3936 * pointers and configuration node handles previously obtained from this
3937 * variable may become invalid.
3938 *
3939 * \par Conforming to:
3940 * LSB 3.2
3941 */
3942snd_config_t *snd_config = NULL;
3943
3944#ifndef DOC_HIDDEN
3945struct finfo {
3946	char *name;
3947	dev_t dev;
3948	ino64_t ino;
3949	time_t mtime;
3950};
3951
3952struct _snd_config_update {
3953	unsigned int count;
3954	struct finfo *finfo;
3955};
3956#endif /* DOC_HIDDEN */
3957
3958static snd_config_update_t *snd_config_global_update = NULL;
3959
3960static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config, snd_config_t *private_data)
3961{
3962	void *h = NULL;
3963	snd_config_t *c, *func_conf = NULL;
3964	char *buf = NULL, errbuf[256];
3965	const char *lib = NULL, *func_name = NULL;
3966	const char *str;
3967	int (*func)(snd_config_t *root, snd_config_t *config, snd_config_t **dst, snd_config_t *private_data) = NULL;
3968	int err;
3969
3970	err = snd_config_search(config, "func", &c);
3971	if (err < 0) {
3972		SNDERR("Field func is missing");
3973		return err;
3974	}
3975	err = snd_config_get_string(c, &str);
3976	if (err < 0) {
3977		SNDERR("Invalid type for field func");
3978		return err;
3979	}
3980	assert(str);
3981	err = snd_config_search_definition(root, "hook_func", str, &func_conf);
3982	if (err >= 0) {
3983		snd_config_iterator_t i, next;
3984		if (snd_config_get_type(func_conf) != SND_CONFIG_TYPE_COMPOUND) {
3985			SNDERR("Invalid type for func %s definition", str);
3986			err = -EINVAL;
3987			goto _err;
3988		}
3989		snd_config_for_each(i, next, func_conf) {
3990			snd_config_t *n = snd_config_iterator_entry(i);
3991			const char *id = n->id;
3992			if (strcmp(id, "comment") == 0)
3993				continue;
3994			if (strcmp(id, "lib") == 0) {
3995				err = snd_config_get_string(n, &lib);
3996				if (err < 0) {
3997					SNDERR("Invalid type for %s", id);
3998					goto _err;
3999				}
4000				continue;
4001			}
4002			if (strcmp(id, "func") == 0) {
4003				err = snd_config_get_string(n, &func_name);
4004				if (err < 0) {
4005					SNDERR("Invalid type for %s", id);
4006					goto _err;
4007				}
4008				continue;
4009			}
4010			SNDERR("Unknown field %s", id);
4011		}
4012	}
4013	if (!func_name) {
4014		int len = 16 + strlen(str) + 1;
4015		buf = malloc(len);
4016		if (! buf) {
4017			err = -ENOMEM;
4018			goto _err;
4019		}
4020		snprintf(buf, len, "snd_config_hook_%s", str);
4021		buf[len-1] = '\0';
4022		func_name = buf;
4023	}
4024	h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
4025	func = h ? snd_dlsym(h, func_name, SND_DLSYM_VERSION(SND_CONFIG_DLSYM_VERSION_HOOK)) : NULL;
4026	err = 0;
4027	if (!h) {
4028		SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
4029		err = -ENOENT;
4030	} else if (!func) {
4031		SNDERR("symbol %s is not defined inside %s", func_name, lib);
4032		snd_dlclose(h);
4033		err = -ENXIO;
4034	}
4035	_err:
4036	if (func_conf)
4037		snd_config_delete(func_conf);
4038	if (err >= 0) {
4039		snd_config_t *nroot;
4040		err = func(root, config, &nroot, private_data);
4041		if (err < 0)
4042			SNDERR("function %s returned error: %s", func_name, snd_strerror(err));
4043		snd_dlclose(h);
4044		if (err >= 0 && nroot)
4045			err = snd_config_substitute(root, nroot);
4046	}
4047	free(buf);
4048	if (err < 0)
4049		return err;
4050	return 0;
4051}
4052
4053static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data)
4054{
4055	snd_config_t *n;
4056	snd_config_iterator_t i, next;
4057	int err, hit, idx = 0;
4058
4059	if ((err = snd_config_search(config, "@hooks", &n)) < 0)
4060		return 0;
4061	snd_config_lock();
4062	snd_config_remove(n);
4063	do {
4064		hit = 0;
4065		snd_config_for_each(i, next, n) {
4066			snd_config_t *n = snd_config_iterator_entry(i);
4067			const char *id = n->id;
4068			long i;
4069			err = safe_strtol(id, &i);
4070			if (err < 0) {
4071				SNDERR("id of field %s is not and integer", id);
4072				err = -EINVAL;
4073				goto _err;
4074			}
4075			if (i == idx) {
4076				err = snd_config_hooks_call(config, n, private_data);
4077				if (err < 0)
4078					goto _err;
4079				idx++;
4080				hit = 1;
4081			}
4082		}
4083	} while (hit);
4084	err = 0;
4085       _err:
4086	snd_config_delete(n);
4087	snd_config_unlock();
4088	return err;
4089}
4090
4091static int config_filename_filter(const struct dirent64 *dirent)
4092{
4093	size_t flen;
4094
4095	if (dirent == NULL)
4096		return 0;
4097	if (dirent->d_type == DT_DIR)
4098		return 0;
4099
4100	flen = strlen(dirent->d_name);
4101	if (flen <= 5)
4102		return 0;
4103
4104	if (strncmp(&dirent->d_name[flen-5], ".conf", 5) == 0)
4105		return 1;
4106
4107	return 0;
4108}
4109
4110static int config_file_open(snd_config_t *root, const char *filename)
4111{
4112	snd_input_t *in;
4113	int err;
4114
4115	err = snd_input_stdio_open(&in, filename, "r");
4116	if (err >= 0) {
4117		err = snd_config_load(root, in);
4118		snd_input_close(in);
4119		if (err < 0)
4120			SNDERR("%s may be old or corrupted: consider to remove or fix it", filename);
4121	} else
4122		SNDERR("cannot access file %s", filename);
4123
4124	return err;
4125}
4126
4127static int config_file_load(snd_config_t *root, const char *fn, int errors)
4128{
4129	struct stat64 st;
4130	struct dirent64 **namelist;
4131	int err, n;
4132
4133	if (!errors && access(fn, R_OK) < 0)
4134		return 1;
4135	if (stat64(fn, &st) < 0) {
4136		SNDERR("cannot stat file/directory %s", fn);
4137		return 1;
4138	}
4139	if (!S_ISDIR(st.st_mode))
4140		return config_file_open(root, fn);
4141#ifndef DOC_HIDDEN
4142#if defined(_GNU_SOURCE) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) && !defined(__sun) && !defined(__ANDROID__)
4143#define SORTFUNC	versionsort64
4144#else
4145#define SORTFUNC	alphasort64
4146#endif
4147#endif
4148	n = scandir64(fn, &namelist, config_filename_filter, SORTFUNC);
4149	if (n > 0) {
4150		int j;
4151		err = 0;
4152		for (j = 0; j < n; ++j) {
4153			if (err >= 0) {
4154				int sl = strlen(fn) + strlen(namelist[j]->d_name) + 2;
4155				char *filename = malloc(sl);
4156				snprintf(filename, sl, "%s/%s", fn, namelist[j]->d_name);
4157				filename[sl-1] = '\0';
4158
4159				err = config_file_open(root, filename);
4160				free(filename);
4161			}
4162			free(namelist[j]);
4163		}
4164		free(namelist);
4165		if (err < 0)
4166			return err;
4167	}
4168	return 0;
4169}
4170
4171static int config_file_load_user(snd_config_t *root, const char *fn, int errors)
4172{
4173	char *fn2;
4174	int err;
4175
4176	err = snd_user_file(fn, &fn2);
4177	if (err < 0)
4178		return config_file_load(root, fn, errors);
4179	err = config_file_load(root, fn2, errors);
4180	free(fn2);
4181	return err;
4182}
4183
4184static int config_file_load_user_all(snd_config_t *_root, snd_config_t *_file, int errors)
4185{
4186	snd_config_t *file = _file, *root = _root, *n;
4187	char *name, *name2, *remain, *rname = NULL;
4188	int err;
4189
4190	if (snd_config_get_type(_file) == SND_CONFIG_TYPE_COMPOUND) {
4191		if ((err = snd_config_search(_file, "file", &file)) < 0) {
4192			SNDERR("Field file not found");
4193			return err;
4194		}
4195		if ((err = snd_config_search(_file, "root", &root)) >= 0) {
4196			err = snd_config_get_ascii(root, &rname);
4197			if (err < 0) {
4198				SNDERR("Field root is bad");
4199				return err;
4200			}
4201			err = snd_config_make_compound(&root, rname, 0);
4202			if (err < 0)
4203				return err;
4204		}
4205	}
4206	if ((err = snd_config_get_ascii(file, &name)) < 0)
4207		goto _err;
4208	name2 = name;
4209	remain = strstr(name, "|||");
4210	while (1) {
4211		if (remain) {
4212			*remain = '\0';
4213			remain += 3;
4214		}
4215		err = config_file_load_user(root, name2, errors);
4216		if (err < 0)
4217			goto _err;
4218		if (err == 0)	/* first hit wins */
4219			break;
4220		if (!remain)
4221			break;
4222		name2 = remain;
4223		remain = strstr(remain, "|||");
4224	}
4225_err:
4226	if (root != _root) {
4227		if (err == 0) {
4228			if (snd_config_get_type(root) == SND_CONFIG_TYPE_COMPOUND) {
4229				if (snd_config_is_empty(root))
4230					goto _del;
4231			}
4232			err = snd_config_make_path(&n, _root, rname, 0, 1);
4233			if (err < 0)
4234				goto _del;
4235			err = snd_config_substitute(n, root);
4236			if (err == 0)
4237				goto _fin;
4238		}
4239_del:
4240		snd_config_delete(root);
4241	}
4242_fin:
4243	free(name);
4244	free(rname);
4245	return err;
4246}
4247
4248/**
4249 * \brief Loads and parses the given configurations files.
4250 * \param[in] root Handle to the root configuration node.
4251 * \param[in] config Handle to the configuration node for this hook.
4252 * \param[out] dst The function puts the handle to the configuration
4253 *                 node loaded from the file(s) at the address specified
4254 *                 by \a dst.
4255 * \param[in] private_data Handle to the private data configuration node.
4256 * \return Zero if successful, otherwise a negative error code.
4257 *
4258 * See \ref confhooks for an example.
4259 */
4260int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t **dst, snd_config_t *private_data)
4261{
4262	snd_config_t *n;
4263	snd_config_iterator_t i, next;
4264	int err, idx = 0, errors = 1, hit;
4265
4266	assert(root && dst);
4267	if ((err = snd_config_search(config, "errors", &n)) >= 0) {
4268		errors = snd_config_get_bool(n);
4269		if (errors < 0) {
4270			SNDERR("Invalid bool value in field errors");
4271			return errors;
4272		}
4273	}
4274	if ((err = snd_config_search(config, "files", &n)) < 0) {
4275		SNDERR("Unable to find field files in the pre-load section");
4276		return -EINVAL;
4277	}
4278	if ((err = snd_config_expand(n, root, NULL, private_data, &n)) < 0) {
4279		SNDERR("Unable to expand filenames in the pre-load section");
4280		return err;
4281	}
4282	if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
4283		SNDERR("Invalid type for field filenames");
4284		goto _err;
4285	}
4286	do {
4287		hit = 0;
4288		snd_config_for_each(i, next, n) {
4289			snd_config_t *n = snd_config_iterator_entry(i);
4290			const char *id = n->id;
4291			long i;
4292			err = safe_strtol(id, &i);
4293			if (err < 0) {
4294				SNDERR("id of field %s is not and integer", id);
4295				err = -EINVAL;
4296				goto _err;
4297			}
4298			if (i == idx) {
4299				err = config_file_load_user_all(root, n, errors);
4300				if (err < 0)
4301					goto _err;
4302				idx++;
4303				hit = 1;
4304			}
4305		}
4306	} while (hit);
4307	*dst = NULL;
4308	err = 0;
4309       _err:
4310	snd_config_delete(n);
4311	return err;
4312}
4313#ifndef DOC_HIDDEN
4314SND_DLSYM_BUILD_VERSION(snd_config_hook_load, SND_CONFIG_DLSYM_VERSION_HOOK);
4315#endif
4316
4317#ifndef DOC_HIDDEN
4318int snd_determine_driver(int card, char **driver);
4319#endif
4320
4321static snd_config_t *_snd_config_hook_private_data(int card, const char *driver)
4322{
4323	snd_config_t *private_data, *v;
4324	int err;
4325
4326	err = snd_config_make_compound(&private_data, NULL, 0);
4327	if (err < 0)
4328		goto __err;
4329	err = snd_config_imake_integer(&v, "integer", card);
4330	if (err < 0)
4331		goto __err;
4332	err = snd_config_add(private_data, v);
4333	if (err < 0) {
4334		snd_config_delete(v);
4335		goto __err;
4336	}
4337	err = snd_config_imake_string(&v, "string", driver);
4338	if (err < 0)
4339		goto __err;
4340	err = snd_config_add(private_data, v);
4341	if (err < 0) {
4342		snd_config_delete(v);
4343		goto __err;
4344	}
4345	return private_data;
4346
4347__err:
4348	snd_config_delete(private_data);
4349	return NULL;
4350}
4351
4352static int _snd_config_hook_table(snd_config_t *root, snd_config_t *config, snd_config_t *private_data)
4353{
4354	snd_config_t *n, *tn;
4355	const char *id;
4356	int err;
4357
4358	if (snd_config_search(config, "table", &n) < 0)
4359		return 0;
4360	if ((err = snd_config_expand(n, root, NULL, private_data, &n)) < 0) {
4361		SNDERR("Unable to expand table compound");
4362		return err;
4363	}
4364	if (snd_config_search(n, "id", &tn) < 0 ||
4365	    snd_config_get_string(tn, &id) < 0) {
4366		SNDERR("Unable to find field table.id");
4367		snd_config_delete(n);
4368		return -EINVAL;
4369	}
4370	if (snd_config_search(n, "value", &tn) < 0 ||
4371	    snd_config_get_type(tn) != SND_CONFIG_TYPE_STRING) {
4372		SNDERR("Unable to find field table.value");
4373		snd_config_delete(n);
4374		return -EINVAL;
4375	}
4376	snd_config_remove(tn);
4377	if ((err = snd_config_set_id(tn, id)) < 0) {
4378		snd_config_delete(tn);
4379		snd_config_delete(n);
4380		return err;
4381	}
4382	snd_config_delete(n);
4383	if ((err = snd_config_add(root, tn)) < 0) {
4384		snd_config_delete(tn);
4385		return err;
4386	}
4387	return 0;
4388}
4389
4390/**
4391 * \brief Loads and parses the given configurations files for each
4392 *        installed sound card.
4393 * \param[in] root Handle to the root configuration node.
4394 * \param[in] config Handle to the configuration node for this hook.
4395 * \param[out] dst The function puts the handle to the configuration
4396 *                 node loaded from the file(s) at the address specified
4397 *                 by \a dst.
4398 * \param[in] private_data Handle to the private data configuration node.
4399 * \return Zero if successful, otherwise a negative error code.
4400 *
4401 * This function works like #snd_config_hook_load, but the files are
4402 * loaded once for each sound card.  The driver name is available with
4403 * the \c private_string function to customize the file name.
4404 */
4405int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, snd_config_t **dst, snd_config_t *private_data ATTRIBUTE_UNUSED)
4406{
4407	int card = -1, err;
4408	snd_config_t *loaded;	// trace loaded cards
4409
4410	err = snd_config_top(&loaded);
4411	if (err < 0)
4412		return err;
4413	do {
4414		err = snd_card_next(&card);
4415		if (err < 0)
4416			goto __fin_err;
4417		if (card >= 0) {
4418			snd_config_t *n, *m, *private_data = NULL;
4419			const char *driver;
4420			char *fdriver = NULL;
4421			bool load;
4422			err = snd_determine_driver(card, &fdriver);
4423			if (err < 0)
4424				goto __fin_err;
4425			if (snd_config_search(root, fdriver, &n) >= 0) {
4426				if (snd_config_get_string(n, &driver) < 0) {
4427					if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
4428						snd_config_get_id(n, &driver);
4429						goto __std;
4430					}
4431					goto __err;
4432				}
4433				while (1) {
4434					char *s = strchr(driver, '.');
4435					if (s == NULL)
4436						break;
4437					driver = s + 1;
4438				}
4439				if (snd_config_search(root, driver, &n) >= 0)
4440					goto __err;
4441			} else {
4442				driver = fdriver;
4443			}
4444		      __std:
4445			load = true;
4446			err = snd_config_imake_integer(&m, driver, 1);
4447			if (err < 0)
4448				goto __err;
4449			err = snd_config_add(loaded, m);
4450			if (err < 0) {
4451				if (err == -EEXIST) {
4452					snd_config_delete(m);
4453					load = false;
4454				} else {
4455					goto __err;
4456				}
4457			}
4458			private_data = _snd_config_hook_private_data(card, driver);
4459			if (!private_data) {
4460				err = -ENOMEM;
4461				goto __err;
4462			}
4463			err = _snd_config_hook_table(root, config, private_data);
4464			if (err < 0)
4465				goto __err;
4466			if (load)
4467				err = snd_config_hook_load(root, config, &n, private_data);
4468		      __err:
4469			if (private_data)
4470				snd_config_delete(private_data);
4471			free(fdriver);
4472			if (err < 0)
4473				goto __fin_err;
4474		}
4475	} while (card >= 0);
4476	snd_config_delete(loaded);
4477	*dst = NULL;
4478	return 0;
4479__fin_err:
4480	snd_config_delete(loaded);
4481	return err;
4482}
4483#ifndef DOC_HIDDEN
4484SND_DLSYM_BUILD_VERSION(snd_config_hook_load_for_all_cards, SND_CONFIG_DLSYM_VERSION_HOOK);
4485#endif
4486
4487/**
4488 * \brief Updates a configuration tree by rereading the configuration files (if needed).
4489 * \param[in,out] _top Address of the handle to the top-level node.
4490 * \param[in,out] _update Address of a pointer to private update information.
4491 * \param[in] cfgs A list of configuration file names, delimited with ':'.
4492 *                 If \p cfgs is \c NULL, the default global
4493 *                 configuration file is used.
4494 * \return 0 if \a _top was up to date, 1 if the configuration files
4495 *         have been reread, otherwise a negative error code.
4496 *
4497 * The variables pointed to by \a _top and \a _update can be initialized
4498 * to \c NULL before the first call to this function.  The private
4499 * update information holds information about all used configuration
4500 * files that allows this function to detects changes to them; this data
4501 * can be freed with #snd_config_update_free.
4502 *
4503 * The global configuration files are specified in the environment variable
4504 * \c ALSA_CONFIG_PATH.
4505 *
4506 * \warning If the configuration tree is reread, all string pointers and
4507 * configuration node handles previously obtained from this tree become
4508 * invalid.
4509 *
4510 * \par Errors:
4511 * Any errors encountered when parsing the input or returned by hooks or
4512 * functions.
4513 */
4514int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, const char *cfgs)
4515{
4516	int err;
4517	const char *configs, *c;
4518	unsigned int k;
4519	size_t l;
4520	snd_config_update_t *local;
4521	snd_config_update_t *update;
4522	snd_config_t *top;
4523
4524	assert(_top && _update);
4525	top = *_top;
4526	update = *_update;
4527	configs = cfgs;
4528	if (!configs) {
4529		configs = getenv(ALSA_CONFIG_PATH_VAR);
4530		if (!configs || !*configs) {
4531			const char *topdir = snd_config_topdir();
4532			char *s = alloca(strlen(topdir) +
4533					 strlen("alsa.conf") + 2);
4534			sprintf(s, "%s/alsa.conf", topdir);
4535			configs = s;
4536		}
4537	}
4538	for (k = 0, c = configs; (l = strcspn(c, ": ")) > 0; ) {
4539		c += l;
4540		k++;
4541		if (!*c)
4542			break;
4543		c++;
4544	}
4545	if (k == 0) {
4546		local = NULL;
4547		goto _reread;
4548	}
4549	local = (snd_config_update_t *)calloc(1, sizeof(snd_config_update_t));
4550	if (!local)
4551		return -ENOMEM;
4552	local->count = k;
4553	local->finfo = calloc(local->count, sizeof(struct finfo));
4554	if (!local->finfo) {
4555		free(local);
4556		return -ENOMEM;
4557	}
4558	for (k = 0, c = configs; (l = strcspn(c, ": ")) > 0; ) {
4559		char name[l + 1];
4560		memcpy(name, c, l);
4561		name[l] = 0;
4562		err = snd_user_file(name, &local->finfo[k].name);
4563		if (err < 0)
4564			goto _end;
4565		c += l;
4566		k++;
4567		if (!*c)
4568			break;
4569		c++;
4570	}
4571	for (k = 0; k < local->count; ++k) {
4572		struct stat64 st;
4573		struct finfo *lf = &local->finfo[k];
4574		if (stat64(lf->name, &st) >= 0) {
4575			lf->dev = st.st_dev;
4576			lf->ino = st.st_ino;
4577			lf->mtime = st.st_mtime;
4578		} else {
4579			SNDERR("Cannot access file %s", lf->name);
4580			free(lf->name);
4581			memmove(&local->finfo[k], &local->finfo[k+1], sizeof(struct finfo) * (local->count - k - 1));
4582			k--;
4583			local->count--;
4584		}
4585	}
4586	if (!update)
4587		goto _reread;
4588	if (local->count != update->count)
4589		goto _reread;
4590	for (k = 0; k < local->count; ++k) {
4591		struct finfo *lf = &local->finfo[k];
4592		struct finfo *uf = &update->finfo[k];
4593		if (strcmp(lf->name, uf->name) != 0 ||
4594		    lf->dev != uf->dev ||
4595		    lf->ino != uf->ino ||
4596		    lf->mtime != uf->mtime)
4597			goto _reread;
4598	}
4599	err = 0;
4600
4601 _end:
4602	if (err < 0) {
4603		if (top) {
4604			snd_config_delete(top);
4605			*_top = NULL;
4606		}
4607		if (update) {
4608			snd_config_update_free(update);
4609			*_update = NULL;
4610		}
4611	}
4612	if (local)
4613		snd_config_update_free(local);
4614	return err;
4615
4616 _reread:
4617 	*_top = NULL;
4618 	*_update = NULL;
4619 	if (update) {
4620 		snd_config_update_free(update);
4621 		update = NULL;
4622 	}
4623	if (top) {
4624		snd_config_delete(top);
4625		top = NULL;
4626	}
4627	err = snd_config_top(&top);
4628	if (err < 0)
4629		goto _end;
4630	if (!local)
4631		goto _skip;
4632	for (k = 0; k < local->count; ++k) {
4633		snd_input_t *in;
4634		err = snd_input_stdio_open(&in, local->finfo[k].name, "r");
4635		if (err >= 0) {
4636			err = snd_config_load(top, in);
4637			snd_input_close(in);
4638			if (err < 0) {
4639				SNDERR("%s may be old or corrupted: consider to remove or fix it", local->finfo[k].name);
4640				goto _end;
4641			}
4642		} else {
4643			SNDERR("cannot access file %s", local->finfo[k].name);
4644		}
4645	}
4646 _skip:
4647	err = snd_config_hooks(top, NULL);
4648	if (err < 0) {
4649		SNDERR("hooks failed, removing configuration");
4650		goto _end;
4651	}
4652	*_top = top;
4653	*_update = local;
4654	return 1;
4655}
4656
4657/**
4658 * \brief Updates #snd_config by rereading the global configuration files (if needed).
4659 * \return 0 if #snd_config was up to date, 1 if #snd_config was
4660 *         updated, otherwise a negative error code.
4661 *
4662 * \warning Whenever #snd_config is updated, all string pointers and
4663 * configuration node handles previously obtained from it may become
4664 * invalid.
4665 * For safer operations, use #snd_config_update_ref and release the config
4666 * via #snd_config_unref.
4667 *
4668 * \par Errors:
4669 * Any errors encountered when parsing the input or returned by hooks or
4670 * functions.
4671 *
4672 * \par Conforming to:
4673 * LSB 3.2
4674 */
4675int snd_config_update(void)
4676{
4677	int err;
4678
4679	snd_config_lock();
4680	err = snd_config_update_r(&snd_config, &snd_config_global_update, NULL);
4681	snd_config_unlock();
4682	return err;
4683}
4684
4685/**
4686 * \brief Updates #snd_config and takes its reference.
4687 * \return 0 if #snd_config was up to date, 1 if #snd_config was
4688 *         updated, otherwise a negative error code.
4689 *
4690 * Unlike #snd_config_update, this function increases a reference counter
4691 * so that the obtained tree won't be deleted until unreferenced by
4692 * #snd_config_unref.
4693 *
4694 * This function is supposed to be thread-safe.
4695 */
4696int snd_config_update_ref(snd_config_t **top)
4697{
4698	int err;
4699
4700	if (top)
4701		*top = NULL;
4702	snd_config_lock();
4703	err = snd_config_update_r(&snd_config, &snd_config_global_update, NULL);
4704	if (err >= 0) {
4705		if (snd_config) {
4706			if (top) {
4707				snd_config->refcount++;
4708				*top = snd_config;
4709			}
4710		} else {
4711			err = -ENODEV;
4712		}
4713	}
4714	snd_config_unlock();
4715	return err;
4716}
4717
4718/**
4719 * \brief Take the reference of the config tree.
4720 *
4721 * Increases a reference counter of the given config tree.
4722 *
4723 * This function is supposed to be thread-safe.
4724 */
4725void snd_config_ref(snd_config_t *cfg)
4726{
4727	snd_config_lock();
4728	if (cfg)
4729		cfg->refcount++;
4730	snd_config_unlock();
4731}
4732
4733/**
4734 * \brief Unreference the config tree.
4735 *
4736 * Decreases a reference counter of the given config tree, and eventually
4737 * deletes the tree if all references are gone.  This is the counterpart of
4738 * #snd_config_unref.
4739 *
4740 * Also, the config taken via #snd_config_update_ref must be unreferenced
4741 * by this function, too.
4742 *
4743 * This function is supposed to be thread-safe.
4744 */
4745void snd_config_unref(snd_config_t *cfg)
4746{
4747	snd_config_lock();
4748	if (cfg)
4749		snd_config_delete(cfg);
4750	snd_config_unlock();
4751}
4752
4753/**
4754 * \brief Frees a private update structure.
4755 * \param[in] update The private update structure to free.
4756 * \return Zero if successful, otherwise a negative error code.
4757 */
4758int snd_config_update_free(snd_config_update_t *update)
4759{
4760	unsigned int k;
4761
4762	assert(update);
4763	for (k = 0; k < update->count; k++)
4764		free(update->finfo[k].name);
4765	free(update->finfo);
4766	free(update);
4767	return 0;
4768}
4769
4770/**
4771 * \brief Frees the global configuration tree in #snd_config.
4772 * \return Zero if successful, otherwise a negative error code.
4773 *
4774 * This functions releases all resources of the global configuration
4775 * tree, and sets #snd_config to \c NULL.
4776 *
4777 * \par Conforming to:
4778 * LSB 3.2
4779 */
4780int snd_config_update_free_global(void)
4781{
4782	snd_config_lock();
4783	if (snd_config)
4784		snd_config_delete(snd_config);
4785	snd_config = NULL;
4786	if (snd_config_global_update)
4787		snd_config_update_free(snd_config_global_update);
4788	snd_config_global_update = NULL;
4789	snd_config_unlock();
4790	/* FIXME: better to place this in another place... */
4791	snd_dlobj_cache_cleanup();
4792
4793	return 0;
4794}
4795
4796/**
4797 * \brief Returns an iterator pointing to a node's first child.
4798 * \param[in] config Handle to a configuration node.
4799 * \return An iterator pointing to \a config's first child.
4800 *
4801 * \a config must be a compound node.
4802 *
4803 * The returned iterator is valid if it is not equal to the return value
4804 * of #snd_config_iterator_end on \a config.
4805 *
4806 * Use #snd_config_iterator_entry to get the handle of the node pointed
4807 * to.
4808 *
4809 * \par Conforming to:
4810 * LSB 3.2
4811 */
4812snd_config_iterator_t snd_config_iterator_first(const snd_config_t *config)
4813{
4814	assert(config->type == SND_CONFIG_TYPE_COMPOUND);
4815	return config->u.compound.fields.next;
4816}
4817
4818/**
4819 * \brief Returns an iterator pointing to the next sibling.
4820 * \param[in] iterator An iterator pointing to a child configuration node.
4821 * \return An iterator pointing to the next sibling of \a iterator.
4822 *
4823 * The returned iterator is valid if it is not equal to the return value
4824 * of #snd_config_iterator_end on the node's parent.
4825 *
4826 * Use #snd_config_iterator_entry to get the handle of the node pointed
4827 * to.
4828 *
4829 * \par Conforming to:
4830 * LSB 3.2
4831 */
4832snd_config_iterator_t snd_config_iterator_next(const snd_config_iterator_t iterator)
4833{
4834	return iterator->next;
4835}
4836
4837/**
4838 * \brief Returns an iterator that ends a node's children list.
4839 * \param[in] config Handle to a configuration node.
4840 * \return An iterator that indicates the end of \a config's children list.
4841 *
4842 * \a config must be a compound node.
4843 *
4844 * The return value can be understood as pointing past the last child of
4845 * \a config.
4846 *
4847 * \par Conforming to:
4848 * LSB 3.2
4849 */
4850snd_config_iterator_t snd_config_iterator_end(const snd_config_t *config)
4851{
4852	assert(config->type == SND_CONFIG_TYPE_COMPOUND);
4853	return (const snd_config_iterator_t)&config->u.compound.fields;
4854}
4855
4856/**
4857 * \brief Returns the configuration node handle pointed to by an iterator.
4858 * \param[in] iterator A configuration node iterator.
4859 * \return The configuration node handle pointed to by \a iterator.
4860 *
4861 * \par Conforming to:
4862 * LSB 3.2
4863 */
4864snd_config_t *snd_config_iterator_entry(const snd_config_iterator_t iterator)
4865{
4866	return list_entry(iterator, snd_config_t, list);
4867}
4868
4869#ifndef DOC_HIDDEN
4870typedef enum _snd_config_walk_pass {
4871	SND_CONFIG_WALK_PASS_PRE,
4872	SND_CONFIG_WALK_PASS_POST,
4873	SND_CONFIG_WALK_PASS_LEAF,
4874} snd_config_walk_pass_t;
4875#endif
4876
4877/* Return 1 if node needs to be attached to parent */
4878/* Return 2 if compound is replaced with standard node */
4879#ifndef DOC_HIDDEN
4880typedef int (*snd_config_walk_callback_t)(snd_config_t *src,
4881					  snd_config_t *root,
4882					  snd_config_t **dst,
4883					  snd_config_walk_pass_t pass,
4884					  snd_config_expand_fcn_t fcn,
4885					  void *private_data);
4886#endif
4887
4888static int snd_config_walk(snd_config_t *src,
4889			   snd_config_t *root,
4890			   snd_config_t **dst,
4891			   snd_config_walk_callback_t callback,
4892			   snd_config_expand_fcn_t fcn,
4893			   void *private_data)
4894{
4895	int err;
4896	snd_config_iterator_t i, next;
4897
4898	switch (snd_config_get_type(src)) {
4899	case SND_CONFIG_TYPE_COMPOUND:
4900		err = callback(src, root, dst, SND_CONFIG_WALK_PASS_PRE, fcn, private_data);
4901		if (err <= 0)
4902			return err;
4903		snd_config_for_each(i, next, src) {
4904			snd_config_t *s = snd_config_iterator_entry(i);
4905			snd_config_t *d = NULL;
4906
4907			err = snd_config_walk(s, root, (dst && *dst) ? &d : NULL,
4908					      callback, fcn, private_data);
4909			if (err < 0)
4910				goto _error;
4911			if (err && d) {
4912				err = snd_config_add(*dst, d);
4913				if (err < 0)
4914					goto _error;
4915			}
4916		}
4917		err = callback(src, root, dst, SND_CONFIG_WALK_PASS_POST, fcn, private_data);
4918		if (err <= 0) {
4919		_error:
4920			if (dst && *dst)
4921				snd_config_delete(*dst);
4922		}
4923		break;
4924	default:
4925		err = callback(src, root, dst, SND_CONFIG_WALK_PASS_LEAF, fcn, private_data);
4926		break;
4927	}
4928	return err;
4929}
4930
4931static int _snd_config_copy(snd_config_t *src,
4932			    snd_config_t *root ATTRIBUTE_UNUSED,
4933			    snd_config_t **dst,
4934			    snd_config_walk_pass_t pass,
4935			    snd_config_expand_fcn_t fcn ATTRIBUTE_UNUSED,
4936			    void *private_data ATTRIBUTE_UNUSED)
4937{
4938	int err;
4939	const char *id = src->id;
4940	snd_config_type_t type = snd_config_get_type(src);
4941	switch (pass) {
4942	case SND_CONFIG_WALK_PASS_PRE:
4943		err = snd_config_make_compound(dst, id, src->u.compound.join);
4944		if (err < 0)
4945			return err;
4946		break;
4947	case SND_CONFIG_WALK_PASS_LEAF:
4948		err = snd_config_make(dst, id, type);
4949		if (err < 0)
4950			return err;
4951		switch (type) {
4952		case SND_CONFIG_TYPE_INTEGER:
4953		{
4954			long v;
4955			err = snd_config_get_integer(src, &v);
4956			assert(err >= 0);
4957			snd_config_set_integer(*dst, v);
4958			break;
4959		}
4960		case SND_CONFIG_TYPE_INTEGER64:
4961		{
4962			long long v;
4963			err = snd_config_get_integer64(src, &v);
4964			assert(err >= 0);
4965			snd_config_set_integer64(*dst, v);
4966			break;
4967		}
4968		case SND_CONFIG_TYPE_REAL:
4969		{
4970			double v;
4971			err = snd_config_get_real(src, &v);
4972			assert(err >= 0);
4973			snd_config_set_real(*dst, v);
4974			break;
4975		}
4976		case SND_CONFIG_TYPE_STRING:
4977		{
4978			const char *s;
4979			err = snd_config_get_string(src, &s);
4980			assert(err >= 0);
4981			err = snd_config_set_string(*dst, s);
4982			if (err < 0)
4983				return err;
4984			break;
4985		}
4986		default:
4987			assert(0);
4988		}
4989		break;
4990	default:
4991		break;
4992	}
4993	return 1;
4994}
4995
4996/**
4997 * \brief Creates a copy of a configuration node.
4998 * \param[out] dst The function puts the handle to the new configuration
4999 *                 node at the address specified by \a dst.
5000 * \param[in] src Handle to the source configuration node.
5001 * \return A non-negative value if successful, otherwise a negative error code.
5002 *
5003 * This function creates a deep copy, i.e., if \a src is a compound
5004 * node, all children are copied recursively.
5005 *
5006 * \par Errors:
5007 * <dl>
5008 * <dt>-ENOMEM<dd>Out of memory.
5009 * </dl>
5010 *
5011 * \par Conforming to:
5012 * LSB 3.2
5013 */
5014int snd_config_copy(snd_config_t **dst,
5015		    snd_config_t *src)
5016{
5017	return snd_config_walk(src, NULL, dst, _snd_config_copy, NULL, NULL);
5018}
5019
5020static int _snd_config_expand_vars(snd_config_t **dst, const char *s, void *private_data)
5021{
5022	snd_config_t *val, *vars = private_data;
5023	if (snd_config_search(vars, s, &val) < 0) {
5024		*dst = NULL;
5025		return 0;
5026	}
5027	return snd_config_copy(dst, val);
5028}
5029
5030static int _snd_config_expand(snd_config_t *src,
5031			      snd_config_t *root ATTRIBUTE_UNUSED,
5032			      snd_config_t **dst,
5033			      snd_config_walk_pass_t pass,
5034			      snd_config_expand_fcn_t fcn,
5035			      void *private_data)
5036{
5037	int err;
5038	const char *id = src->id;
5039	snd_config_type_t type = snd_config_get_type(src);
5040	switch (pass) {
5041	case SND_CONFIG_WALK_PASS_PRE:
5042	{
5043		if (id && strcmp(id, "@args") == 0)
5044			return 0;
5045		err = snd_config_make_compound(dst, id, src->u.compound.join);
5046		if (err < 0)
5047			return err;
5048		break;
5049	}
5050	case SND_CONFIG_WALK_PASS_LEAF:
5051		switch (type) {
5052		case SND_CONFIG_TYPE_INTEGER:
5053		{
5054			long v;
5055			err = snd_config_get_integer(src, &v);
5056			assert(err >= 0);
5057			err = snd_config_imake_integer(dst, id, v);
5058			if (err < 0)
5059				return err;
5060			break;
5061		}
5062		case SND_CONFIG_TYPE_INTEGER64:
5063		{
5064			long long v;
5065			err = snd_config_get_integer64(src, &v);
5066			assert(err >= 0);
5067			err = snd_config_imake_integer64(dst, id, v);
5068			if (err < 0)
5069				return err;
5070			break;
5071		}
5072		case SND_CONFIG_TYPE_REAL:
5073		{
5074			double v;
5075			err = snd_config_get_real(src, &v);
5076			assert(err >= 0);
5077			err = snd_config_imake_real(dst, id, v);
5078			if (err < 0)
5079				return err;
5080			break;
5081		}
5082		case SND_CONFIG_TYPE_STRING:
5083		{
5084			const char *s;
5085			snd_config_t *vars = private_data;
5086			snd_config_get_string(src, &s);
5087			if (s && *s == '$') {
5088				err = snd_config_evaluate_string(dst, s, fcn, vars);
5089				if (err < 0)
5090					return err;
5091				if (*dst == NULL)
5092					return 0;
5093				err = snd_config_set_id(*dst, id);
5094				if (err < 0) {
5095					snd_config_delete(*dst);
5096					return err;
5097				}
5098			} else {
5099				err = snd_config_imake_string(dst, id, s);
5100				if (err < 0)
5101					return err;
5102			}
5103			break;
5104		}
5105		default:
5106			assert(0);
5107		}
5108		break;
5109	default:
5110		break;
5111	}
5112	return 1;
5113}
5114
5115static int _snd_config_evaluate(snd_config_t *src,
5116				snd_config_t *root,
5117				snd_config_t **dst ATTRIBUTE_UNUSED,
5118				snd_config_walk_pass_t pass,
5119				snd_config_expand_fcn_t fcn ATTRIBUTE_UNUSED,
5120				void *private_data)
5121{
5122	int err;
5123	if (pass == SND_CONFIG_WALK_PASS_PRE) {
5124		char *buf = NULL, errbuf[256];
5125		const char *lib = NULL, *func_name = NULL;
5126		const char *str;
5127		int (*func)(snd_config_t **dst, snd_config_t *root,
5128			    snd_config_t *src, snd_config_t *private_data) = NULL;
5129		void *h = NULL;
5130		snd_config_t *c, *func_conf = NULL;
5131		err = snd_config_search(src, "@func", &c);
5132		if (err < 0)
5133			return 1;
5134		err = snd_config_get_string(c, &str);
5135		if (err < 0) {
5136			SNDERR("Invalid type for @func");
5137			return err;
5138		}
5139		assert(str);
5140		err = snd_config_search_definition(root, "func", str, &func_conf);
5141		if (err >= 0) {
5142			snd_config_iterator_t i, next;
5143			if (snd_config_get_type(func_conf) != SND_CONFIG_TYPE_COMPOUND) {
5144				SNDERR("Invalid type for func %s definition", str);
5145				err = -EINVAL;
5146				goto _err;
5147			}
5148			snd_config_for_each(i, next, func_conf) {
5149				snd_config_t *n = snd_config_iterator_entry(i);
5150				const char *id = n->id;
5151				if (strcmp(id, "comment") == 0)
5152					continue;
5153				if (strcmp(id, "lib") == 0) {
5154					err = snd_config_get_string(n, &lib);
5155					if (err < 0) {
5156						SNDERR("Invalid type for %s", id);
5157						goto _err;
5158					}
5159					continue;
5160				}
5161				if (strcmp(id, "func") == 0) {
5162					err = snd_config_get_string(n, &func_name);
5163					if (err < 0) {
5164						SNDERR("Invalid type for %s", id);
5165						goto _err;
5166					}
5167					continue;
5168				}
5169				SNDERR("Unknown field %s", id);
5170			}
5171		}
5172		if (!func_name) {
5173			int len = 9 + strlen(str) + 1;
5174			buf = malloc(len);
5175			if (! buf) {
5176				err = -ENOMEM;
5177				goto _err;
5178			}
5179			snprintf(buf, len, "snd_func_%s", str);
5180			buf[len-1] = '\0';
5181			func_name = buf;
5182		}
5183		h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
5184		if (h)
5185			func = snd_dlsym(h, func_name, SND_DLSYM_VERSION(SND_CONFIG_DLSYM_VERSION_EVALUATE));
5186		err = 0;
5187		if (!h) {
5188			SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
5189			err = -ENOENT;
5190			goto _errbuf;
5191		} else if (!func) {
5192			SNDERR("symbol %s is not defined inside %s", func_name, lib);
5193			snd_dlclose(h);
5194			err = -ENXIO;
5195			goto _errbuf;
5196		}
5197	       _err:
5198		if (func_conf)
5199			snd_config_delete(func_conf);
5200		if (err >= 0) {
5201			snd_config_t *eval;
5202			err = func(&eval, root, src, private_data);
5203			if (err < 0)
5204				SNDERR("function %s returned error: %s", func_name, snd_strerror(err));
5205			snd_dlclose(h);
5206			if (err >= 0 && eval)
5207				err = snd_config_substitute(src, eval);
5208		}
5209	       _errbuf:
5210		free(buf);
5211		if (err < 0)
5212			return err;
5213		return 0;
5214	}
5215	return 1;
5216}
5217
5218/**
5219 * \brief Evaluates a configuration node at runtime.
5220 * \param[in,out] config Handle to the source configuration node.
5221 * \param[in] root Handle to the root of the source configuration.
5222 * \param[in] private_data Handle to the private data node for runtime evaluation.
5223 * \param result Must be \c NULL.
5224 * \return A non-negative value if successful, otherwise a negative error code.
5225 *
5226 * This function evaluates any functions (\c \@func) in \a config and
5227 * replaces those nodes with the respective function results.
5228 */
5229int snd_config_evaluate(snd_config_t *config, snd_config_t *root,
5230		        snd_config_t *private_data, snd_config_t **result)
5231{
5232	/* FIXME: Only in place evaluation is currently implemented */
5233	assert(result == NULL);
5234	return snd_config_walk(config, root, result, _snd_config_evaluate, NULL, private_data);
5235}
5236
5237static int load_defaults(snd_config_t *subs, snd_config_t *defs)
5238{
5239	snd_config_iterator_t d, dnext;
5240	snd_config_for_each(d, dnext, defs) {
5241		snd_config_t *def = snd_config_iterator_entry(d);
5242		snd_config_iterator_t f, fnext;
5243		if (snd_config_get_type(def) != SND_CONFIG_TYPE_COMPOUND)
5244			continue;
5245		snd_config_for_each(f, fnext, def) {
5246			snd_config_t *fld = snd_config_iterator_entry(f);
5247			const char *id = fld->id;
5248			if (strcmp(id, "type") == 0)
5249				continue;
5250			if (strcmp(id, "default") == 0) {
5251				snd_config_t *deflt;
5252				int err;
5253				err = snd_config_copy(&deflt, fld);
5254				if (err < 0)
5255					return err;
5256				err = snd_config_set_id(deflt, def->id);
5257				if (err < 0) {
5258					snd_config_delete(deflt);
5259					return err;
5260				}
5261				err = snd_config_add(subs, deflt);
5262				if (err < 0) {
5263					snd_config_delete(deflt);
5264					return err;
5265				}
5266				continue;
5267			}
5268			SNDERR("Unknown field %s", id);
5269			return -EINVAL;
5270		}
5271	}
5272	return 0;
5273}
5274
5275static void skip_blank(const char **ptr)
5276{
5277	while (1) {
5278		switch (**ptr) {
5279		case ' ':
5280		case '\f':
5281		case '\t':
5282		case '\n':
5283		case '\r':
5284			break;
5285		default:
5286			return;
5287		}
5288		(*ptr)++;
5289	}
5290}
5291
5292static int parse_char(const char **ptr)
5293{
5294	int c;
5295	assert(**ptr == '\\');
5296	(*ptr)++;
5297	c = **ptr;
5298	switch (c) {
5299	case 'n':
5300		c = '\n';
5301		break;
5302	case 't':
5303		c = '\t';
5304		break;
5305	case 'v':
5306		c = '\v';
5307		break;
5308	case 'b':
5309		c = '\b';
5310		break;
5311	case 'r':
5312		c = '\r';
5313		break;
5314	case 'f':
5315		c = '\f';
5316		break;
5317	case '0': case '1': case '2': case '3':
5318	case '4': case '5': case '6': case '7':
5319	{
5320		int num = c - '0';
5321		int i = 1;
5322		(*ptr)++;
5323		do {
5324			c = **ptr;
5325			if (c < '0' || c > '7')
5326				break;
5327			num = num * 8 + c - '0';
5328			i++;
5329			(*ptr)++;
5330		} while (i < 3);
5331		return num;
5332	}
5333	default:
5334		break;
5335	}
5336	(*ptr)++;
5337	return c;
5338}
5339
5340static int parse_id(const char **ptr)
5341{
5342	if (!**ptr)
5343		return -EINVAL;
5344	while (1) {
5345		switch (**ptr) {
5346		case '\f':
5347		case '\t':
5348		case '\n':
5349		case '\r':
5350		case ',':
5351		case '=':
5352		case '\0':
5353			return 0;
5354		default:
5355			break;
5356		}
5357		(*ptr)++;
5358	}
5359}
5360
5361static int parse_string(const char **ptr, char **val)
5362{
5363	const size_t bufsize = 256;
5364	char _buf[bufsize];
5365	char *buf = _buf;
5366	size_t alloc = bufsize;
5367	char delim = **ptr;
5368	size_t idx = 0;
5369	(*ptr)++;
5370	while (1) {
5371		int c = **ptr;
5372		switch (c) {
5373		case '\0':
5374			SNDERR("Unterminated string");
5375			return -EINVAL;
5376		case '\\':
5377			c = parse_char(ptr);
5378			if (c < 0) {
5379				if (alloc > bufsize)
5380					free(buf);
5381				return c;
5382			}
5383			break;
5384		default:
5385			(*ptr)++;
5386			if (c == delim) {
5387				*val = malloc(idx + 1);
5388				if (!*val)
5389					return -ENOMEM;
5390				memcpy(*val, buf, idx);
5391				(*val)[idx] = 0;
5392				if (alloc > bufsize)
5393					free(buf);
5394				return 0;
5395			}
5396		}
5397		if (idx >= alloc) {
5398			size_t old_alloc = alloc;
5399			alloc *= 2;
5400			if (old_alloc == bufsize) {
5401				buf = malloc(alloc);
5402				if (!buf)
5403					return -ENOMEM;
5404				memcpy(buf, _buf, old_alloc);
5405			} else {
5406				char *buf2 = realloc(buf, alloc);
5407				if (!buf2) {
5408					free(buf);
5409					return -ENOMEM;
5410				}
5411				buf = buf2;
5412			}
5413		}
5414		buf[idx++] = c;
5415	}
5416}
5417
5418
5419/* Parse var=val or val */
5420static int parse_arg(const char **ptr, unsigned int *varlen, char **val)
5421{
5422	const char *str;
5423	int err, vallen;
5424	skip_blank(ptr);
5425	str = *ptr;
5426	if (*str == '"' || *str == '\'') {
5427		err = parse_string(ptr, val);
5428		if (err < 0)
5429			return err;
5430		*varlen = 0;
5431		return 0;
5432	}
5433	err = parse_id(ptr);
5434	if (err < 0)
5435		return err;
5436	vallen = *ptr - str;
5437	skip_blank(ptr);
5438	if (**ptr != '=') {
5439		*varlen = 0;
5440		goto _value;
5441	}
5442	*varlen = vallen;
5443	(*ptr)++;
5444	skip_blank(ptr);
5445	str = *ptr;
5446	if (*str == '"' || *str == '\'') {
5447		err = parse_string(ptr, val);
5448		if (err < 0)
5449			return err;
5450		return 0;
5451	}
5452	err = parse_id(ptr);
5453	if (err < 0)
5454		return err;
5455	vallen = *ptr - str;
5456 _value:
5457	*val = malloc(vallen + 1);
5458	if (!*val)
5459		return -ENOMEM;
5460	memcpy(*val, str, vallen);
5461	(*val)[vallen] = 0;
5462	return 0;
5463}
5464
5465
5466/* val1, val2, ...
5467 * var1=val1,var2=val2,...
5468 * { conf syntax }
5469 */
5470static int parse_args(snd_config_t *subs, const char *str, snd_config_t *defs)
5471{
5472	int err;
5473	int arg = 0;
5474	if (str == NULL)
5475		return 0;
5476	skip_blank(&str);
5477	if (!*str)
5478		return 0;
5479	if (*str == '{') {
5480		int len = strlen(str);
5481		snd_input_t *input;
5482		snd_config_iterator_t i, next;
5483		while (1) {
5484			switch (str[--len]) {
5485			case ' ':
5486			case '\f':
5487			case '\t':
5488			case '\n':
5489			case '\r':
5490				continue;
5491			default:
5492				break;
5493			}
5494			break;
5495		}
5496		if (str[len] != '}')
5497			return -EINVAL;
5498		err = snd_input_buffer_open(&input, str + 1, len - 1);
5499		if (err < 0)
5500			return err;
5501		err = snd_config_load_override(subs, input);
5502		snd_input_close(input);
5503		if (err < 0)
5504			return err;
5505		snd_config_for_each(i, next, subs) {
5506			snd_config_t *n = snd_config_iterator_entry(i);
5507			snd_config_t *d;
5508			const char *id = n->id;
5509			err = snd_config_search(defs, id, &d);
5510			if (err < 0) {
5511				SNDERR("Unknown parameter %s", id);
5512				return err;
5513			}
5514		}
5515		return 0;
5516	}
5517
5518	while (1) {
5519		char buf[256];
5520		const char *var = buf;
5521		unsigned int varlen;
5522		snd_config_t *def, *sub, *typ;
5523		const char *new = str;
5524		const char *tmp;
5525		char *val = NULL;
5526
5527		sub = NULL;
5528		err = parse_arg(&new, &varlen, &val);
5529		if (err < 0)
5530			goto _err;
5531		if (varlen > 0) {
5532			assert(varlen < sizeof(buf));
5533			memcpy(buf, str, varlen);
5534			buf[varlen] = 0;
5535		} else {
5536			sprintf(buf, "%d", arg);
5537		}
5538		err = snd_config_search_alias(defs, NULL, var, &def);
5539		if (err < 0) {
5540			SNDERR("Unknown parameter %s", var);
5541			goto _err;
5542		}
5543		if (snd_config_get_type(def) != SND_CONFIG_TYPE_COMPOUND) {
5544			SNDERR("Parameter %s definition is not correct", var);
5545			err = -EINVAL;
5546			goto _err;
5547		}
5548		var = def->id;
5549		err = snd_config_search(subs, var, &sub);
5550		if (err >= 0)
5551			snd_config_delete(sub);
5552		sub = NULL;
5553		err = snd_config_search(def, "type", &typ);
5554		if (err < 0) {
5555		_invalid_type:
5556			SNDERR("Parameter %s definition is missing a valid type info", var);
5557			goto _err;
5558		}
5559		err = snd_config_get_string(typ, &tmp);
5560		if (err < 0 || !tmp)
5561			goto _invalid_type;
5562		if (strcmp(tmp, "integer") == 0) {
5563			long v;
5564			err = snd_config_make(&sub, var, SND_CONFIG_TYPE_INTEGER);
5565			if (err < 0)
5566				goto _err;
5567			err = safe_strtol(val, &v);
5568			if (err < 0) {
5569				SNDERR("Parameter %s must be an integer", var);
5570				goto _err;
5571			}
5572			err = snd_config_set_integer(sub, v);
5573			if (err < 0)
5574				goto _err;
5575		} else if (strcmp(tmp, "integer64") == 0) {
5576			long long v;
5577			err = snd_config_make(&sub, var, SND_CONFIG_TYPE_INTEGER64);
5578			if (err < 0)
5579				goto _err;
5580			err = safe_strtoll(val, &v);
5581			if (err < 0) {
5582				SNDERR("Parameter %s must be an integer", var);
5583				goto _err;
5584			}
5585			err = snd_config_set_integer64(sub, v);
5586			if (err < 0)
5587				goto _err;
5588		} else if (strcmp(tmp, "real") == 0) {
5589			double v;
5590			err = snd_config_make(&sub, var, SND_CONFIG_TYPE_REAL);
5591			if (err < 0)
5592				goto _err;
5593			err = safe_strtod(val, &v);
5594			if (err < 0) {
5595				SNDERR("Parameter %s must be a real", var);
5596				goto _err;
5597			}
5598			err = snd_config_set_real(sub, v);
5599			if (err < 0)
5600				goto _err;
5601		} else if (strcmp(tmp, "string") == 0) {
5602			err = snd_config_make(&sub, var, SND_CONFIG_TYPE_STRING);
5603			if (err < 0)
5604				goto _err;
5605			err = snd_config_set_string(sub, val);
5606			if (err < 0)
5607				goto _err;
5608		} else {
5609			err = -EINVAL;
5610			goto _invalid_type;
5611		}
5612		err = snd_config_set_id(sub, var);
5613		if (err < 0)
5614			goto _err;
5615		err = snd_config_add(subs, sub);
5616		if (err < 0) {
5617		_err:
5618			if (sub)
5619				snd_config_delete(sub);
5620			free(val);
5621			return err;
5622		}
5623		free(val);
5624		if (!*new)
5625			break;
5626		if (*new != ',')
5627			return -EINVAL;
5628		str = new + 1;
5629		arg++;
5630	}
5631	return 0;
5632}
5633
5634/**
5635 * \brief Expands a configuration node, applying arguments and functions.
5636 * \param[in] config Handle to the configuration node.
5637 * \param[in] root Handle to the root configuration node.
5638 * \param[in] fcn Custom function to obtain the referred variable name
5639 * \param[in] private_data Private data node for the custom function
5640 * \param[out] result The function puts the handle to the result
5641 *                    configuration node at the address specified by
5642 *                    \a result.
5643 * \return A non-negative value if successful, otherwise a negative error code.
5644 *
5645 * If \a config has arguments (defined by a child with id \c \@args),
5646 * this function replaces any string node beginning with $ with the
5647 * respective argument value, or the default argument value, or nothing.
5648 * Furthermore, any functions are evaluated (see #snd_config_evaluate).
5649 * The resulting copy of \a config is returned in \a result.
5650 *
5651 * The new tree is not evaluated (\ref snd_config_evaluate).
5652 */
5653int snd_config_expand_custom(snd_config_t *config, snd_config_t *root,
5654			     snd_config_expand_fcn_t fcn, void *private_data,
5655			     snd_config_t **result)
5656{
5657	snd_config_t *res;
5658	int err;
5659
5660	err = snd_config_walk(config, root, &res, _snd_config_expand, fcn, private_data);
5661	if (err < 0) {
5662		SNDERR("Expand error (walk): %s", snd_strerror(err));
5663		return err;
5664	}
5665	*result = res;
5666	return 1;
5667}
5668
5669/**
5670 * \brief Expands a configuration node, applying arguments and functions.
5671 * \param[in] config Handle to the configuration node.
5672 * \param[in] root Handle to the root configuration node.
5673 * \param[in] args Arguments string, can be \c NULL.
5674 * \param[in] private_data Handle to the private data node for functions.
5675 * \param[out] result The function puts the handle to the result
5676 *                    configuration node at the address specified by
5677 *                    \a result.
5678 * \return A non-negative value if successful, otherwise a negative error code.
5679 *
5680 * If \a config has arguments (defined by a child with id \c \@args),
5681 * this function replaces any string node beginning with $ with the
5682 * respective argument value, or the default argument value, or nothing.
5683 * Furthermore, any functions are evaluated (see #snd_config_evaluate).
5684 * The resulting copy of \a config is returned in \a result.
5685 */
5686int snd_config_expand(snd_config_t *config, snd_config_t *root, const char *args,
5687		      snd_config_t *private_data, snd_config_t **result)
5688{
5689	int err;
5690	snd_config_t *defs, *subs = NULL, *res;
5691	err = snd_config_search(config, "@args", &defs);
5692	if (err < 0) {
5693		if (args != NULL) {
5694			SNDERR("Unknown parameters %s", args);
5695			return -EINVAL;
5696		}
5697		err = snd_config_copy(&res, config);
5698		if (err < 0)
5699			return err;
5700	} else {
5701		err = snd_config_top(&subs);
5702		if (err < 0)
5703			return err;
5704		err = load_defaults(subs, defs);
5705		if (err < 0) {
5706			SNDERR("Load defaults error: %s", snd_strerror(err));
5707			goto _end;
5708		}
5709		err = parse_args(subs, args, defs);
5710		if (err < 0) {
5711			SNDERR("Parse arguments error: %s", snd_strerror(err));
5712			goto _end;
5713		}
5714		err = snd_config_evaluate(subs, root, private_data, NULL);
5715		if (err < 0) {
5716			SNDERR("Args evaluate error: %s", snd_strerror(err));
5717			goto _end;
5718		}
5719		err = snd_config_walk(config, root, &res, _snd_config_expand, _snd_config_expand_vars, subs);
5720		if (err < 0) {
5721			SNDERR("Expand error (walk): %s", snd_strerror(err));
5722			goto _end;
5723		}
5724	}
5725	err = snd_config_evaluate(res, root, private_data, NULL);
5726	if (err < 0) {
5727		SNDERR("Evaluate error: %s", snd_strerror(err));
5728		snd_config_delete(res);
5729		goto _end;
5730	}
5731	*result = res;
5732	err = 1;
5733 _end:
5734 	if (subs)
5735		snd_config_delete(subs);
5736	return err;
5737}
5738
5739/**
5740 * \brief Searches for a definition in a configuration tree, using
5741 *        aliases and expanding hooks and arguments.
5742 * \param[in] config Handle to the configuration (sub)tree to search.
5743 * \param[in] base Implicit key base, or \c NULL for none.
5744 * \param[in] name Key suffix, optionally with arguments.
5745 * \param[out] result The function puts the handle to the expanded found
5746 *                    node at the address specified by \a result.
5747 * \return A non-negative value if successful, otherwise a negative error code.
5748 *
5749 * This functions searches for a child node of \a config, allowing
5750 * aliases and expanding hooks, like #snd_config_search_alias_hooks.
5751 *
5752 * If \a name contains a colon (:), the rest of the string after the
5753 * colon contains arguments that are expanded as with
5754 * #snd_config_expand.
5755 *
5756 * In any case, \a result is a new node that must be freed by the
5757 * caller.
5758 *
5759 * \par Errors:
5760 * <dl>
5761 * <dt>-ENOENT<dd>An id in \a key or an alias id does not exist.
5762 * <dt>-ENOENT<dd>\a config or one of its child nodes to be searched is
5763 *                not a compound node.
5764 * </dl>
5765 * Additionally, any errors encountered when parsing the hook
5766 * definitions or arguments, or returned by (hook) functions.
5767 */
5768int snd_config_search_definition(snd_config_t *config,
5769				 const char *base, const char *name,
5770				 snd_config_t **result)
5771{
5772	snd_config_t *conf;
5773	char *key;
5774	const char *args = strchr(name, ':');
5775	int err;
5776	if (args) {
5777		args++;
5778		key = alloca(args - name);
5779		memcpy(key, name, args - name - 1);
5780		key[args - name - 1] = '\0';
5781	} else {
5782		key = (char *) name;
5783	}
5784	/*
5785	 *  if key contains dot (.), the implicit base is ignored
5786	 *  and the key starts from root given by the 'config' parameter
5787	 */
5788	snd_config_lock();
5789	err = snd_config_search_alias_hooks(config, strchr(key, '.') ? NULL : base, key, &conf);
5790	if (err < 0) {
5791		snd_config_unlock();
5792		return err;
5793	}
5794	err = snd_config_expand(conf, config, args, NULL, result);
5795	snd_config_unlock();
5796	return err;
5797}
5798
5799#ifndef DOC_HIDDEN
5800void snd_config_set_hop(snd_config_t *conf, int hop)
5801{
5802	conf->hop = hop;
5803}
5804
5805int snd_config_check_hop(snd_config_t *conf)
5806{
5807	if (conf) {
5808		if (conf->hop >= SND_CONF_MAX_HOPS) {
5809			SYSERR("Too many definition levels (looped?)\n");
5810			return -EINVAL;
5811		}
5812		return conf->hop;
5813	}
5814	return 0;
5815}
5816#endif
5817
5818#if 0
5819/* Not strictly needed, but useful to check for memory leaks */
5820void _snd_config_end(void) __attribute__ ((destructor));
5821
5822static void _snd_config_end(void)
5823{
5824	int k;
5825	if (snd_config)
5826		snd_config_delete(snd_config);
5827	snd_config = 0;
5828	for (k = 0; k < files_info_count; ++k)
5829		free(files_info[k].name);
5830	free(files_info);
5831	files_info = NULL;
5832	files_info_count = 0;
5833}
5834#endif
5835
5836#ifndef DOC_HIDDEN
5837size_t page_size(void)
5838{
5839	long s = sysconf(_SC_PAGE_SIZE);
5840	assert(s > 0);
5841	return s;
5842}
5843
5844size_t page_align(size_t size)
5845{
5846	size_t r;
5847	long psz = page_size();
5848	r = size % psz;
5849	if (r)
5850		return size + psz - r;
5851	return size;
5852}
5853
5854size_t page_ptr(size_t object_offset, size_t object_size, size_t *offset, size_t *mmap_offset)
5855{
5856	size_t r;
5857	long psz = page_size();
5858	assert(offset);
5859	assert(mmap_offset);
5860	*mmap_offset = object_offset;
5861	object_offset %= psz;
5862	*mmap_offset -= object_offset;
5863	object_size += object_offset;
5864	r = object_size % psz;
5865	if (r)
5866		r = object_size + psz - r;
5867	else
5868		r = object_size;
5869	*offset = object_offset;
5870	return r;
5871}
5872#endif /* DOC_HIDDEN */
5873