OSDN Git Service

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