]>
git.proxmox.com Git - libgit2.git/blob - src/config.c
2 * This file is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2,
4 * as published by the Free Software Foundation.
6 * In addition to the permissions in the GNU General Public License,
7 * the authors give you unlimited permission to link the compiled
8 * version of this file into combinations with other programs,
9 * and to distribute those combinations without any restriction
10 * coming from the use of this file. (The General Public License
11 * restrictions do apply in other respects; for example, they cover
12 * modification of the file, and distribution when not linked into
13 * a combined executable.)
15 * This file is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
28 #include "hashtable.h"
30 #include "git2/config_backend.h"
36 git_config_backend
*backend
;
40 int git_config_open_bare(git_config
**out
, const char *path
)
42 git_config_backend
*backend
= NULL
;
43 git_config
*cfg
= NULL
;
44 int error
= GIT_SUCCESS
;
46 error
= git_config_new(&cfg
);
47 if (error
< GIT_SUCCESS
)
50 error
= git_config_backend_file(&backend
, path
);
51 if (error
< GIT_SUCCESS
)
54 error
= git_config_add_backend(cfg
, backend
, 1);
55 if (error
< GIT_SUCCESS
)
58 error
= backend
->open(backend
);
59 if (error
< GIT_SUCCESS
)
68 backend
->free(backend
);
73 int git_config_open_global(git_config
**out
)
75 char full_path
[GIT_PATH_MAX
];
78 home
= getenv("HOME");
80 return git__throw(GIT_EOSERR
, "Failed to find $HOME variable");
82 git__joinpath(full_path
, home
, GIT_CONFIG_FILENAME
);
84 return git_config_open_bare(out
, filename
);
87 void git_config_free(git_config
*cfg
)
90 git_config_backend
*backend
;
91 backend_internal
*internal
;
93 for(i
= 0; i
< cfg
->backends
.length
; ++i
){
94 internal
= git_vector_get(&cfg
->backends
, i
);
95 backend
= internal
->backend
;
96 backend
->free(backend
);
100 git_vector_free(&cfg
->backends
);
104 static int config_backend_cmp(const void *a
, const void *b
)
106 const backend_internal
*bk_a
= *(const backend_internal
**)(a
);
107 const backend_internal
*bk_b
= *(const backend_internal
**)(b
);
109 return bk_b
->priority
- bk_a
->priority
;
112 int git_config_new(git_config
**out
)
116 cfg
= git__malloc(sizeof(git_config
));
120 memset(cfg
, 0x0, sizeof(git_config
));
122 if (git_vector_init(&cfg
->backends
, 3, config_backend_cmp
) < 0) {
132 int git_config_add_backend(git_config
*cfg
, git_config_backend
*backend
, int priority
)
134 backend_internal
*internal
;
136 assert(cfg
&& backend
);
138 internal
= git__malloc(sizeof(backend_internal
));
139 if (internal
== NULL
)
142 internal
->backend
= backend
;
143 internal
->priority
= priority
;
145 if (git_vector_insert(&cfg
->backends
, internal
) < 0) {
150 git_vector_sort(&cfg
->backends
);
151 internal
->backend
->cfg
= cfg
;
157 * Loop over all the variables
160 int git_config_foreach(git_config
*cfg
, int (*fn
)(const char *, void *), void *data
)
162 int ret
= GIT_SUCCESS
;
164 backend_internal
*internal
;
165 git_config_backend
*backend
;
167 for(i
= 0; i
< cfg
->backends
.length
&& ret
== 0; ++i
) {
168 internal
= git_vector_get(&cfg
->backends
, i
);
169 backend
= internal
->backend
;
170 ret
= backend
->foreach(backend
, fn
, data
);
182 * Internal function to actually set the string value of a variable
185 int git_config_set_long(git_config
*cfg
, const char *name
, long int value
)
187 char str_value
[5]; /* Most numbers should fit in here */
188 int buf_len
= sizeof(str_value
), ret
;
189 char *help_buf
= NULL
;
191 if ((ret
= snprintf(str_value
, buf_len
, "%ld", value
)) >= buf_len
- 1){
192 /* The number is too large, we need to allocate more memory */
194 help_buf
= git__malloc(buf_len
);
195 snprintf(help_buf
, buf_len
, "%ld", value
);
196 ret
= git_config_set_string(cfg
, name
, help_buf
);
199 ret
= git_config_set_string(cfg
, name
, str_value
);
205 int git_config_set_int(git_config
*cfg
, const char *name
, int value
)
207 return git_config_set_long(cfg
, name
, value
);
210 int git_config_set_bool(git_config
*cfg
, const char *name
, int value
)
212 const char *str_value
;
219 return git_config_set_string(cfg
, name
, str_value
);
222 int git_config_set_string(git_config
*cfg
, const char *name
, const char *value
)
224 backend_internal
*internal
;
225 git_config_backend
*backend
;
227 assert(cfg
->backends
.length
> 0);
229 internal
= git_vector_get(&cfg
->backends
, 0);
230 backend
= internal
->backend
;
232 return backend
->set(backend
, name
, value
);
239 int git_config_get_long(git_config
*cfg
, const char *name
, long int *out
)
241 const char *value
, *num_end
;
245 ret
= git_config_get_string(cfg
, name
, &value
);
246 if (ret
< GIT_SUCCESS
)
249 ret
= git__strtol32(&num
, value
, &num_end
, 0);
250 if (ret
< GIT_SUCCESS
)
266 num
*= 1024 * 1024 * 1024;
269 return GIT_EINVALIDTYPE
;
277 int git_config_get_int(git_config
*cfg
, const char *name
, int *out
)
282 ret
= git_config_get_long(cfg
, name
, &tmp
);
289 int git_config_get_bool(git_config
*cfg
, const char *name
, int *out
)
292 int error
= GIT_SUCCESS
;
294 error
= git_config_get_string(cfg
, name
, &value
);
295 if (error
< GIT_SUCCESS
)
298 /* A missing value means true */
304 if (!strcasecmp(value
, "true") ||
305 !strcasecmp(value
, "yes") ||
306 !strcasecmp(value
, "on")) {
310 if (!strcasecmp(value
, "false") ||
311 !strcasecmp(value
, "no") ||
312 !strcasecmp(value
, "off")) {
317 /* Try to parse it as an integer */
318 error
= git_config_get_int(cfg
, name
, out
);
319 if (error
== GIT_SUCCESS
)
325 int git_config_get_string(git_config
*cfg
, const char *name
, const char **out
)
327 backend_internal
*internal
;
328 git_config_backend
*backend
;
330 assert(cfg
->backends
.length
> 0);
332 internal
= git_vector_get(&cfg
->backends
, 0);
333 backend
= internal
->backend
;
335 return backend
->get(backend
, name
, out
);