OSDN Git Service

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