2 * config.c : reading configuration information
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
26 #define APR_WANT_STRFUNC
27 #define APR_WANT_MEMFUNC
30 #include <apr_general.h>
33 #include "svn_error.h"
34 #include "svn_pools.h"
35 #include "config_impl.h"
37 #include "svn_private_config.h"
38 #include "private/svn_dep_compat.h"
43 /* Section table entries. */
44 typedef struct cfg_section_t cfg_section_t;
47 /* The section name. */
50 /* Table of cfg_option_t's. */
55 /* Option table entries. */
56 typedef struct cfg_option_t cfg_option_t;
59 /* The option name. */
62 /* The option name, converted into a hash key. */
65 /* The unexpanded option value. */
68 /* The expanded option value. */
71 /* Expansion flag. If this is TRUE, this value has already been expanded.
72 In this case, if x_value is NULL, no expansions were necessary,
73 and value should be used directly. */
74 svn_boolean_t expanded;
80 svn_config_create2(svn_config_t **cfgp,
81 svn_boolean_t section_names_case_sensitive,
82 svn_boolean_t option_names_case_sensitive,
83 apr_pool_t *result_pool)
85 svn_config_t *cfg = apr_palloc(result_pool, sizeof(*cfg));
87 cfg->sections = apr_hash_make(result_pool);
88 cfg->pool = result_pool;
89 cfg->x_pool = svn_pool_create(result_pool);
90 cfg->x_values = FALSE;
91 cfg->tmp_key = svn_stringbuf_create_empty(result_pool);
92 cfg->tmp_value = svn_stringbuf_create_empty(result_pool);
93 cfg->section_names_case_sensitive = section_names_case_sensitive;
94 cfg->option_names_case_sensitive = option_names_case_sensitive;
101 svn_config_read3(svn_config_t **cfgp, const char *file,
102 svn_boolean_t must_exist,
103 svn_boolean_t section_names_case_sensitive,
104 svn_boolean_t option_names_case_sensitive,
105 apr_pool_t *result_pool)
110 SVN_ERR(svn_config_create2(&cfg,
111 section_names_case_sensitive,
112 option_names_case_sensitive,
115 /* Yes, this is platform-specific code in Subversion, but there's no
116 practical way to migrate it into APR, as it's simultaneously
117 Subversion-specific and Windows-specific. Even if we eventually
118 want to have APR offer a generic config-reading interface, it
119 makes sense to test it here first and migrate it later. */
121 if (0 == strncmp(file, SVN_REGISTRY_PREFIX, SVN_REGISTRY_PREFIX_LEN))
122 err = svn_config__parse_registry(cfg, file + SVN_REGISTRY_PREFIX_LEN,
123 must_exist, result_pool);
126 err = svn_config__parse_file(cfg, file, must_exist, result_pool);
128 if (err != SVN_NO_ERROR)
137 svn_config_parse(svn_config_t **cfgp, svn_stream_t *stream,
138 svn_boolean_t section_names_case_sensitive,
139 svn_boolean_t option_names_case_sensitive,
140 apr_pool_t *result_pool)
144 apr_pool_t *scratch_pool = svn_pool_create(result_pool);
146 err = svn_config_create2(&cfg,
147 section_names_case_sensitive,
148 option_names_case_sensitive,
151 if (err == SVN_NO_ERROR)
152 err = svn_config__parse_stream(cfg, stream, result_pool, scratch_pool);
154 if (err == SVN_NO_ERROR)
157 svn_pool_destroy(scratch_pool);
162 /* Read various configuration sources into *CFGP, in this order, with
163 * later reads overriding the results of earlier ones:
165 * 1. SYS_REGISTRY_PATH (only on Win32, but ignored if NULL)
167 * 2. SYS_FILE_PATH (everywhere, but ignored if NULL)
169 * 3. USR_REGISTRY_PATH (only on Win32, but ignored if NULL)
171 * 4. USR_FILE_PATH (everywhere, but ignored if NULL)
173 * Allocate *CFGP in POOL. Even if no configurations are read,
174 * allocate an empty *CFGP.
177 read_all(svn_config_t **cfgp,
178 const char *sys_registry_path,
179 const char *usr_registry_path,
180 const char *sys_file_path,
181 const char *usr_file_path,
184 svn_boolean_t red_config = FALSE; /* "red" is the past tense of "read" */
186 /*** Read system-wide configurations first... ***/
189 if (sys_registry_path)
191 SVN_ERR(svn_config_read2(cfgp, sys_registry_path, FALSE, FALSE, pool));
199 SVN_ERR(svn_config_merge(*cfgp, sys_file_path, FALSE));
202 SVN_ERR(svn_config_read3(cfgp, sys_file_path,
203 FALSE, FALSE, FALSE, pool));
208 /*** ...followed by per-user configurations. ***/
211 if (usr_registry_path)
214 SVN_ERR(svn_config_merge(*cfgp, usr_registry_path, FALSE));
217 SVN_ERR(svn_config_read2(cfgp, usr_registry_path,
218 FALSE, FALSE, pool));
227 SVN_ERR(svn_config_merge(*cfgp, usr_file_path, FALSE));
230 SVN_ERR(svn_config_read3(cfgp, usr_file_path,
231 FALSE, FALSE, FALSE, pool));
237 SVN_ERR(svn_config_create2(cfgp, FALSE, FALSE, pool));
243 /* CONFIG_DIR provides an override for the default behavior of reading
244 the default set of overlay files described by read_all()'s doc
247 get_category_config(svn_config_t **cfg,
248 const char *config_dir,
249 const char *category,
252 const char *usr_reg_path = NULL, *sys_reg_path = NULL;
253 const char *usr_cfg_path, *sys_cfg_path;
254 svn_error_t *err = NULL;
261 sys_reg_path = apr_pstrcat(pool, SVN_REGISTRY_SYS_CONFIG_PATH,
263 usr_reg_path = apr_pstrcat(pool, SVN_REGISTRY_USR_CONFIG_PATH,
267 err = svn_config__sys_config_path(&sys_cfg_path, category, pool);
268 if ((err) && (err->apr_err == SVN_ERR_BAD_FILENAME))
271 svn_error_clear(err);
279 SVN_ERR(svn_config_get_user_config_path(&usr_cfg_path, config_dir, category,
281 return read_all(cfg, sys_reg_path, usr_reg_path,
282 sys_cfg_path, usr_cfg_path, pool);
287 svn_config_get_config(apr_hash_t **cfg_hash,
288 const char *config_dir,
292 *cfg_hash = apr_hash_make(pool);
294 #define CATLEN (sizeof(SVN_CONFIG_CATEGORY_SERVERS) - 1)
295 SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_SERVERS,
298 apr_hash_set(*cfg_hash, SVN_CONFIG_CATEGORY_SERVERS, CATLEN, cfg);
301 #define CATLEN (sizeof(SVN_CONFIG_CATEGORY_CONFIG) - 1)
302 SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_CONFIG,
305 apr_hash_set(*cfg_hash, SVN_CONFIG_CATEGORY_CONFIG, CATLEN, cfg);
313 /* Iterate through CFG, passing BATON to CALLBACK for every (SECTION, OPTION)
314 pair. Stop if CALLBACK returns TRUE. Allocate from POOL. */
316 for_each_option(svn_config_t *cfg, void *baton, apr_pool_t *pool,
317 svn_boolean_t callback(void *same_baton,
318 cfg_section_t *section,
319 cfg_option_t *option))
321 apr_hash_index_t *sec_ndx;
322 for (sec_ndx = apr_hash_first(pool, cfg->sections);
324 sec_ndx = apr_hash_next(sec_ndx))
328 apr_hash_index_t *opt_ndx;
330 apr_hash_this(sec_ndx, NULL, NULL, &sec_ptr);
333 for (opt_ndx = apr_hash_first(pool, sec->options);
335 opt_ndx = apr_hash_next(opt_ndx))
340 apr_hash_this(opt_ndx, NULL, NULL, &opt_ptr);
343 if (callback(baton, sec, opt))
352 merge_callback(void *baton, cfg_section_t *section, cfg_option_t *option)
354 svn_config_set(baton, section->name, option->name, option->value);
359 svn_config_merge(svn_config_t *cfg, const char *file,
360 svn_boolean_t must_exist)
362 /* The original config hash shouldn't change if there's an error
363 while reading the confguration, so read into a temporary table.
364 ### We could use a tmp subpool for this, since merge_cfg is going
365 to be tossed afterwards. Premature optimization, though? */
366 svn_config_t *merge_cfg;
367 SVN_ERR(svn_config_read3(&merge_cfg, file, must_exist,
368 cfg->section_names_case_sensitive,
369 cfg->option_names_case_sensitive,
372 /* Now copy the new options into the original table. */
373 for_each_option(merge_cfg, cfg, merge_cfg->pool, merge_callback);
379 /* Remove variable expansions from CFG. Walk through the options tree,
380 killing all expanded values, then clear the expanded value pool. */
382 rmex_callback(void *baton, cfg_section_t *section, cfg_option_t *option)
384 /* Only clear the `expanded' flag if the value actually contains
385 variable expansions. */
386 if (option->expanded && option->x_value != NULL)
388 option->x_value = NULL;
389 option->expanded = FALSE;
396 remove_expansions(svn_config_t *cfg)
401 for_each_option(cfg, NULL, cfg->x_pool, rmex_callback);
402 svn_pool_clear(cfg->x_pool);
403 cfg->x_values = FALSE;
408 /* Canonicalize a string for hashing. Modifies KEY in place. */
409 static APR_INLINE char *
410 make_hash_key(char *key)
413 for (p = key; *p != 0; ++p)
414 *p = (char)apr_tolower(*p);
419 /* Return a pointer to an option in CFG, or NULL if it doesn't exist.
420 if SECTIONP is non-null, return a pointer to the option's section.
421 OPTION may be NULL. */
422 static cfg_option_t *
423 find_option(svn_config_t *cfg, const char *section, const char *option,
424 cfg_section_t **sectionp)
428 /* Canonicalize the hash key */
429 svn_stringbuf_set(cfg->tmp_key, section);
430 if (! cfg->section_names_case_sensitive)
431 make_hash_key(cfg->tmp_key->data);
433 sec_ptr = apr_hash_get(cfg->sections, cfg->tmp_key->data,
435 if (sectionp != NULL)
438 if (sec_ptr != NULL && option != NULL)
440 cfg_section_t *sec = sec_ptr;
443 /* Canonicalize the option key */
444 svn_stringbuf_set(cfg->tmp_key, option);
445 if (! cfg->option_names_case_sensitive)
446 make_hash_key(cfg->tmp_key->data);
448 opt = apr_hash_get(sec->options, cfg->tmp_key->data,
450 /* NOTE: ConfigParser's sections are case sensitive. */
452 && apr_strnatcasecmp(section, SVN_CONFIG__DEFAULT_SECTION) != 0)
453 /* Options which aren't found in the requested section are
454 also sought after in the default section. */
455 opt = find_option(cfg, SVN_CONFIG__DEFAULT_SECTION, option, &sec);
463 /* Has a bi-directional dependency with make_string_from_option(). */
465 expand_option_value(svn_config_t *cfg, cfg_section_t *section,
466 const char *opt_value, const char **opt_x_valuep,
470 /* Set *VALUEP according to the OPT's value. A value for X_POOL must
471 only ever be passed into this function by expand_option_value(). */
473 make_string_from_option(const char **valuep, svn_config_t *cfg,
474 cfg_section_t *section, cfg_option_t *opt,
477 /* Expand the option value if necessary. */
480 /* before attempting to expand an option, check for the placeholder.
481 * If none is there, there is no point in calling expand_option_value.
483 if (opt->value && strchr(opt->value, '%'))
485 apr_pool_t *tmp_pool = (x_pool ? x_pool : svn_pool_create(cfg->x_pool));
487 expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool);
488 opt->expanded = TRUE;
492 /* Grab the fully expanded value from tmp_pool before its
495 opt->x_value = apr_pstrmemdup(cfg->x_pool, opt->x_value,
496 strlen(opt->x_value));
497 svn_pool_destroy(tmp_pool);
502 opt->expanded = TRUE;
507 *valuep = opt->x_value;
509 *valuep = opt->value;
513 /* Start of variable-replacement placeholder */
514 #define FMT_START "%("
515 #define FMT_START_LEN (sizeof(FMT_START) - 1)
517 /* End of variable-replacement placeholder */
519 #define FMT_END_LEN (sizeof(FMT_END) - 1)
522 /* Expand OPT_VALUE (which may be NULL) in SECTION into *OPT_X_VALUEP.
523 If no variable replacements are done, set *OPT_X_VALUEP to
524 NULL. Allocate from X_POOL. */
526 expand_option_value(svn_config_t *cfg, cfg_section_t *section,
527 const char *opt_value, const char **opt_x_valuep,
530 svn_stringbuf_t *buf = NULL;
531 const char *parse_from = opt_value;
532 const char *copy_from = parse_from;
533 const char *name_start, *name_end;
535 while (parse_from != NULL
536 && *parse_from != '\0'
537 && (name_start = strstr(parse_from, FMT_START)) != NULL)
539 name_start += FMT_START_LEN;
540 if (*name_start == '\0')
541 /* FMT_START at end of opt_value. */
544 name_end = strstr(name_start, FMT_END);
545 if (name_end != NULL)
548 apr_size_t len = name_end - name_start;
549 char *name = apr_pstrmemdup(x_pool, name_start, len);
551 x_opt = find_option(cfg, section->name, name, NULL);
557 /* Pass back the sub-pool originally provided by
558 make_string_from_option() as an indication of when it
560 make_string_from_option(&cstring, cfg, section, x_opt, x_pool);
562 /* Append the plain text preceding the expansion. */
563 len = name_start - FMT_START_LEN - copy_from;
566 buf = svn_stringbuf_ncreate(copy_from, len, x_pool);
567 cfg->x_values = TRUE;
570 svn_stringbuf_appendbytes(buf, copy_from, len);
572 /* Append the expansion and adjust parse pointers. */
573 svn_stringbuf_appendcstr(buf, cstring);
574 parse_from = name_end + FMT_END_LEN;
575 copy_from = parse_from;
578 /* Though ConfigParser considers the failure to resolve
579 the requested expansion an exception condition, we
580 consider it to be plain text, and look for the start of
582 parse_from = name_end + FMT_END_LEN;
585 /* Though ConfigParser treats unterminated format specifiers
586 as an exception condition, we consider them to be plain
587 text. The fact that there are no more format specifier
588 endings means we're done parsing. */
594 /* Copy the remainder of the plain text. */
595 svn_stringbuf_appendcstr(buf, copy_from);
596 *opt_x_valuep = buf->data;
599 *opt_x_valuep = NULL;
602 static cfg_section_t *
603 svn_config_addsection(svn_config_t *cfg,
607 const char *hash_key;
609 s = apr_palloc(cfg->pool, sizeof(cfg_section_t));
610 s->name = apr_pstrdup(cfg->pool, section);
611 if(cfg->section_names_case_sensitive)
614 hash_key = make_hash_key(apr_pstrdup(cfg->pool, section));
615 s->options = apr_hash_make(cfg->pool);
616 svn_hash_sets(cfg->sections, hash_key, s);
622 svn_config_create_option(cfg_option_t **opt,
625 svn_boolean_t option_names_case_sensitive,
630 o = apr_palloc(pool, sizeof(cfg_option_t));
631 o->name = apr_pstrdup(pool, option);
632 if(option_names_case_sensitive)
633 o->hash_key = o->name;
635 o->hash_key = make_hash_key(apr_pstrdup(pool, option));
637 o->value = apr_pstrdup(pool, value);
646 svn_config_get(svn_config_t *cfg, const char **valuep,
647 const char *section, const char *option,
648 const char *default_value)
650 *valuep = default_value;
654 cfg_option_t *opt = find_option(cfg, section, option, &sec);
657 make_string_from_option(valuep, cfg, sec, opt, NULL);
660 /* before attempting to expand an option, check for the placeholder.
661 * If none is there, there is no point in calling expand_option_value.
663 if (default_value && strchr(default_value, '%'))
665 apr_pool_t *tmp_pool = svn_pool_create(cfg->x_pool);
666 const char *x_default;
667 expand_option_value(cfg, sec, default_value, &x_default, tmp_pool);
670 svn_stringbuf_set(cfg->tmp_value, x_default);
671 *valuep = cfg->tmp_value->data;
673 svn_pool_destroy(tmp_pool);
681 svn_config_set(svn_config_t *cfg,
682 const char *section, const char *option,
688 remove_expansions(cfg);
690 opt = find_option(cfg, section, option, &sec);
693 /* Replace the option's value. */
694 opt->value = apr_pstrdup(cfg->pool, value);
695 opt->expanded = FALSE;
699 /* Create a new option */
700 svn_config_create_option(&opt, option, value,
701 cfg->option_names_case_sensitive,
706 /* Even the section doesn't exist. Create it. */
707 sec = svn_config_addsection(cfg, section);
710 svn_hash_sets(sec->options, opt->hash_key, opt);
715 /* Set *BOOLP to true or false depending (case-insensitively) on INPUT.
716 If INPUT is null, set *BOOLP to DEFAULT_VALUE.
718 INPUT is a string indicating truth or falsehood in any of the usual
719 ways: "true"/"yes"/"on"/etc, "false"/"no"/"off"/etc.
721 If INPUT is neither NULL nor a recognized string, return an error
722 with code SVN_ERR_BAD_CONFIG_VALUE; use SECTION and OPTION in
723 constructing the error string. */
725 get_bool(svn_boolean_t *boolp, const char *input, svn_boolean_t default_value,
726 const char *section, const char *option)
728 svn_tristate_t value = svn_tristate__from_word(input);
730 if (value == svn_tristate_true)
732 else if (value == svn_tristate_false)
734 else if (input == NULL) /* no value provided */
735 *boolp = default_value;
737 else if (section) /* unrecognized value */
738 return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
739 _("Config error: invalid boolean "
740 "value '%s' for '[%s] %s'"),
741 input, section, option);
743 return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
744 _("Config error: invalid boolean "
745 "value '%s' for '%s'"),
753 svn_config_get_bool(svn_config_t *cfg, svn_boolean_t *valuep,
754 const char *section, const char *option,
755 svn_boolean_t default_value)
757 const char *tmp_value;
758 svn_config_get(cfg, &tmp_value, section, option, NULL);
759 return get_bool(valuep, tmp_value, default_value, section, option);
765 svn_config_set_bool(svn_config_t *cfg,
766 const char *section, const char *option,
769 svn_config_set(cfg, section, option,
770 (value ? SVN_CONFIG_TRUE : SVN_CONFIG_FALSE));
774 svn_config_get_int64(svn_config_t *cfg,
778 apr_int64_t default_value)
780 const char *tmp_value;
781 svn_config_get(cfg, &tmp_value, section, option, NULL);
783 return svn_cstring_strtoi64(valuep, tmp_value,
784 APR_INT64_MIN, APR_INT64_MAX, 10);
786 *valuep = default_value;
791 svn_config_set_int64(svn_config_t *cfg,
796 svn_config_set(cfg, section, option,
797 apr_psprintf(cfg->pool, "%" APR_INT64_T_FMT, value));
801 svn_config_get_yes_no_ask(svn_config_t *cfg, const char **valuep,
802 const char *section, const char *option,
803 const char* default_value)
805 const char *tmp_value;
807 svn_config_get(cfg, &tmp_value, section, option, NULL);
810 tmp_value = default_value;
812 if (tmp_value && (0 == svn_cstring_casecmp(tmp_value, SVN_CONFIG_ASK)))
814 *valuep = SVN_CONFIG_ASK;
818 svn_boolean_t bool_val;
819 /* We already incorporated default_value into tmp_value if
820 necessary, so the FALSE below will be ignored unless the
821 caller is doing something it shouldn't be doing. */
822 SVN_ERR(get_bool(&bool_val, tmp_value, FALSE, section, option));
823 *valuep = bool_val ? SVN_CONFIG_TRUE : SVN_CONFIG_FALSE;
830 svn_config_get_tristate(svn_config_t *cfg, svn_tristate_t *valuep,
831 const char *section, const char *option,
832 const char *unknown_value,
833 svn_tristate_t default_value)
835 const char *tmp_value;
837 svn_config_get(cfg, &tmp_value, section, option, NULL);
841 *valuep = default_value;
843 else if (0 == svn_cstring_casecmp(tmp_value, unknown_value))
845 *valuep = svn_tristate_unknown;
849 svn_boolean_t bool_val;
850 /* We already incorporated default_value into tmp_value if
851 necessary, so the FALSE below will be ignored unless the
852 caller is doing something it shouldn't be doing. */
853 SVN_ERR(get_bool(&bool_val, tmp_value, FALSE, section, option));
854 *valuep = bool_val ? svn_tristate_true : svn_tristate_false;
861 svn_config_enumerate_sections(svn_config_t *cfg,
862 svn_config_section_enumerator_t callback,
865 apr_hash_index_t *sec_ndx;
867 apr_pool_t *subpool = svn_pool_create(cfg->x_pool);
869 for (sec_ndx = apr_hash_first(subpool, cfg->sections);
871 sec_ndx = apr_hash_next(sec_ndx))
876 apr_hash_this(sec_ndx, NULL, NULL, &sec_ptr);
879 if (!callback(sec->name, baton))
883 svn_pool_destroy(subpool);
889 svn_config_enumerate_sections2(svn_config_t *cfg,
890 svn_config_section_enumerator2_t callback,
891 void *baton, apr_pool_t *pool)
893 apr_hash_index_t *sec_ndx;
894 apr_pool_t *iteration_pool;
897 iteration_pool = svn_pool_create(pool);
898 for (sec_ndx = apr_hash_first(pool, cfg->sections);
900 sec_ndx = apr_hash_next(sec_ndx))
905 apr_hash_this(sec_ndx, NULL, NULL, &sec_ptr);
908 svn_pool_clear(iteration_pool);
909 if (!callback(sec->name, baton, iteration_pool))
912 svn_pool_destroy(iteration_pool);
920 svn_config_enumerate(svn_config_t *cfg, const char *section,
921 svn_config_enumerator_t callback, void *baton)
924 apr_hash_index_t *opt_ndx;
928 find_option(cfg, section, NULL, &sec);
932 subpool = svn_pool_create(cfg->x_pool);
934 for (opt_ndx = apr_hash_first(subpool, sec->options);
936 opt_ndx = apr_hash_next(opt_ndx))
940 const char *temp_value;
942 apr_hash_this(opt_ndx, NULL, NULL, &opt_ptr);
946 make_string_from_option(&temp_value, cfg, sec, opt, NULL);
947 if (!callback(opt->name, temp_value, baton))
951 svn_pool_destroy(subpool);
957 svn_config_enumerate2(svn_config_t *cfg, const char *section,
958 svn_config_enumerator2_t callback, void *baton,
962 apr_hash_index_t *opt_ndx;
963 apr_pool_t *iteration_pool;
966 find_option(cfg, section, NULL, &sec);
970 iteration_pool = svn_pool_create(pool);
972 for (opt_ndx = apr_hash_first(pool, sec->options);
974 opt_ndx = apr_hash_next(opt_ndx))
978 const char *temp_value;
980 apr_hash_this(opt_ndx, NULL, NULL, &opt_ptr);
984 make_string_from_option(&temp_value, cfg, sec, opt, NULL);
985 svn_pool_clear(iteration_pool);
986 if (!callback(opt->name, temp_value, baton, iteration_pool))
989 svn_pool_destroy(iteration_pool);
996 /* Baton for search_groups() */
997 struct search_groups_baton
999 const char *key; /* Provided by caller of svn_config_find_group */
1000 const char *match; /* Filled in by search_groups */
1005 /* This is an `svn_config_enumerator_t' function, and BATON is a
1006 * `struct search_groups_baton *'.
1008 static svn_boolean_t search_groups(const char *name,
1013 struct search_groups_baton *b = baton;
1014 apr_array_header_t *list;
1016 list = svn_cstring_split(value, ",", TRUE, pool);
1017 if (svn_cstring_match_glob_list(b->key, list))
1019 /* Fill in the match and return false, to stop enumerating. */
1020 b->match = apr_pstrdup(b->pool, name);
1028 const char *svn_config_find_group(svn_config_t *cfg, const char *key,
1029 const char *master_section,
1032 struct search_groups_baton gb;
1037 (void) svn_config_enumerate2(cfg, master_section, search_groups, &gb, pool);
1043 svn_config_get_server_setting(svn_config_t *cfg,
1044 const char* server_group,
1045 const char* option_name,
1046 const char* default_value)
1049 svn_config_get(cfg, &retval, SVN_CONFIG_SECTION_GLOBAL,
1050 option_name, default_value);
1053 svn_config_get(cfg, &retval, server_group, option_name, retval);
1060 svn_config_dup(svn_config_t **cfgp,
1064 apr_hash_index_t *sectidx;
1065 apr_hash_index_t *optidx;
1068 SVN_ERR(svn_config_create2(cfgp, FALSE, FALSE, pool));
1070 (*cfgp)->x_values = src->x_values;
1071 (*cfgp)->section_names_case_sensitive = src->section_names_case_sensitive;
1072 (*cfgp)->option_names_case_sensitive = src->option_names_case_sensitive;
1074 for (sectidx = apr_hash_first(pool, src->sections);
1076 sectidx = apr_hash_next(sectidx))
1078 const void *sectkey;
1080 apr_ssize_t sectkeyLength;
1081 cfg_section_t * srcsect;
1082 cfg_section_t * destsec;
1084 apr_hash_this(sectidx, §key, §keyLength, §val);
1087 destsec = svn_config_addsection(*cfgp, srcsect->name);
1089 for (optidx = apr_hash_first(pool, srcsect->options);
1091 optidx = apr_hash_next(optidx))
1095 apr_ssize_t optkeyLength;
1096 cfg_option_t *srcopt;
1097 cfg_option_t *destopt;
1099 apr_hash_this(optidx, &optkey, &optkeyLength, &optval);
1102 svn_config_create_option(&destopt, srcopt->name, srcopt->value,
1103 (*cfgp)->option_names_case_sensitive,
1106 destopt->value = apr_pstrdup(pool, srcopt->value);
1107 destopt->x_value = apr_pstrdup(pool, srcopt->x_value);
1108 destopt->expanded = srcopt->expanded;
1109 apr_hash_set(destsec->options,
1110 apr_pstrdup(pool, (const char*)optkey),
1111 optkeyLength, destopt);
1115 return SVN_NO_ERROR;
1119 svn_config_copy_config(apr_hash_t **cfg_hash,
1120 apr_hash_t *src_hash,
1123 apr_hash_index_t *cidx;
1125 *cfg_hash = apr_hash_make(pool);
1126 for (cidx = apr_hash_first(pool, src_hash);
1128 cidx = apr_hash_next(cidx))
1132 apr_ssize_t ckeyLength;
1133 svn_config_t * srcconfig;
1134 svn_config_t * destconfig;
1136 apr_hash_this(cidx, &ckey, &ckeyLength, &cval);
1139 SVN_ERR(svn_config_dup(&destconfig, srcconfig, pool));
1141 apr_hash_set(*cfg_hash,
1142 apr_pstrdup(pool, (const char*)ckey),
1143 ckeyLength, destconfig);
1146 return SVN_NO_ERROR;
1150 svn_config_get_server_setting_int(svn_config_t *cfg,
1151 const char *server_group,
1152 const char *option_name,
1153 apr_int64_t default_value,
1154 apr_int64_t *result_value,
1157 const char* tmp_value;
1160 tmp_value = svn_config_get_server_setting(cfg, server_group,
1162 if (tmp_value == NULL)
1163 *result_value = default_value;
1166 /* read tmp_value as an int now */
1167 *result_value = apr_strtoi64(tmp_value, &end_pos, 0);
1171 return svn_error_createf
1172 (SVN_ERR_BAD_CONFIG_VALUE, NULL,
1173 _("Config error: invalid integer value '%s'"),
1178 return SVN_NO_ERROR;
1182 svn_config_get_server_setting_bool(svn_config_t *cfg,
1183 svn_boolean_t *valuep,
1184 const char *server_group,
1185 const char *option_name,
1186 svn_boolean_t default_value)
1188 const char* tmp_value;
1189 tmp_value = svn_config_get_server_setting(cfg, server_group,
1191 return get_bool(valuep, tmp_value, default_value,
1192 server_group, option_name);
1197 svn_config_has_section(svn_config_t *cfg, const char *section)
1201 /* Canonicalize the hash key */
1202 svn_stringbuf_set(cfg->tmp_key, section);
1203 if (! cfg->section_names_case_sensitive)
1204 make_hash_key(cfg->tmp_key->data);
1206 sec = svn_hash_gets(cfg->sections, cfg->tmp_key->data);