]>
git.proxmox.com Git - libgit2.git/blob - src/config.c
2 * Copyright (C) 2009-2011 the libgit2 contributors
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
10 #include "hashtable.h"
12 #include "git2/config.h"
18 git_config_file
*file
;
22 void git_config_free(git_config
*cfg
)
25 git_config_file
*file
;
26 file_internal
*internal
;
31 for(i
= 0; i
< cfg
->files
.length
; ++i
){
32 internal
= git_vector_get(&cfg
->files
, i
);
33 file
= internal
->file
;
38 git_vector_free(&cfg
->files
);
42 static int config_backend_cmp(const void *a
, const void *b
)
44 const file_internal
*bk_a
= (const file_internal
*)(a
);
45 const file_internal
*bk_b
= (const file_internal
*)(b
);
47 return bk_b
->priority
- bk_a
->priority
;
50 int git_config_new(git_config
**out
)
54 cfg
= git__malloc(sizeof(git_config
));
58 memset(cfg
, 0x0, sizeof(git_config
));
60 if (git_vector_init(&cfg
->files
, 3, config_backend_cmp
) < 0) {
70 int git_config_add_file_ondisk(git_config
*cfg
, const char *path
, int priority
)
72 git_config_file
*file
= NULL
;
75 error
= git_config_file__ondisk(&file
, path
);
76 if (error
< GIT_SUCCESS
)
79 error
= git_config_add_file(cfg
, file
, priority
);
80 if (error
< GIT_SUCCESS
) {
82 * free manually; the file is not owned by the config
83 * instance yet and will not be freed on cleanup
92 int git_config_open_ondisk(git_config
**cfg
, const char *path
)
96 error
= git_config_new(cfg
);
97 if (error
< GIT_SUCCESS
)
100 error
= git_config_add_file_ondisk(*cfg
, path
, 1);
101 if (error
< GIT_SUCCESS
)
102 git_config_free(*cfg
);
107 int git_config_add_file(git_config
*cfg
, git_config_file
*file
, int priority
)
109 file_internal
*internal
;
114 if ((error
= file
->open(file
)) < GIT_SUCCESS
)
115 return git__rethrow(error
, "Failed to open config file");
117 internal
= git__malloc(sizeof(file_internal
));
118 if (internal
== NULL
)
121 internal
->file
= file
;
122 internal
->priority
= priority
;
124 if (git_vector_insert(&cfg
->files
, internal
) < 0) {
129 git_vector_sort(&cfg
->files
);
130 internal
->file
->cfg
= cfg
;
136 * Loop over all the variables
139 int git_config_foreach(git_config
*cfg
, int (*fn
)(const char *, const char *, void *), void *data
)
141 int ret
= GIT_SUCCESS
;
143 file_internal
*internal
;
144 git_config_file
*file
;
146 for(i
= 0; i
< cfg
->files
.length
&& ret
== 0; ++i
) {
147 internal
= git_vector_get(&cfg
->files
, i
);
148 file
= internal
->file
;
149 ret
= file
->foreach(file
, fn
, data
);
155 int git_config_delete(git_config
*cfg
, const char *name
)
157 return git_config_set_string(cfg
, name
, NULL
);
164 int git_config_set_long(git_config
*cfg
, const char *name
, long int value
)
166 char str_value
[32]; /* All numbers should fit in here */
167 p_snprintf(str_value
, sizeof(str_value
), "%ld", value
);
168 return git_config_set_string(cfg
, name
, str_value
);
171 int git_config_set_int(git_config
*cfg
, const char *name
, int value
)
173 return git_config_set_long(cfg
, name
, value
);
176 int git_config_set_bool(git_config
*cfg
, const char *name
, int value
)
178 return git_config_set_string(cfg
, name
, value
? "true" : "false");
181 int git_config_set_string(git_config
*cfg
, const char *name
, const char *value
)
183 file_internal
*internal
;
184 git_config_file
*file
;
186 if (cfg
->files
.length
== 0)
187 return git__throw(GIT_EINVALIDARGS
, "Cannot set variable value; no files open in the `git_config` instance");
189 internal
= git_vector_get(&cfg
->files
, 0);
190 file
= internal
->file
;
192 return file
->set(file
, name
, value
);
199 int git_config_get_long(git_config
*cfg
, const char *name
, long int *out
)
201 const char *value
, *num_end
;
205 ret
= git_config_get_string(cfg
, name
, &value
);
206 if (ret
< GIT_SUCCESS
)
207 return git__rethrow(ret
, "Failed to get value for %s", name
);
209 ret
= git__strtol32(&num
, value
, &num_end
, 0);
210 if (ret
< GIT_SUCCESS
)
211 return git__rethrow(ret
, "Failed to get value for %s", name
);
226 num
*= 1024 * 1024 * 1024;
229 return git__throw(GIT_EINVALIDTYPE
, "Failed to get value for %s. Value is of invalid type", name
);
237 int git_config_get_int(git_config
*cfg
, const char *name
, int *out
)
242 ret
= git_config_get_long(cfg
, name
, &tmp
);
249 int git_config_get_bool(git_config
*cfg
, const char *name
, int *out
)
252 int error
= GIT_SUCCESS
;
254 error
= git_config_get_string(cfg
, name
, &value
);
255 if (error
< GIT_SUCCESS
)
256 return git__rethrow(error
, "Failed to get value for %s", name
);
258 /* A missing value means true */
264 if (!strcasecmp(value
, "true") ||
265 !strcasecmp(value
, "yes") ||
266 !strcasecmp(value
, "on")) {
270 if (!strcasecmp(value
, "false") ||
271 !strcasecmp(value
, "no") ||
272 !strcasecmp(value
, "off")) {
277 /* Try to parse it as an integer */
278 error
= git_config_get_int(cfg
, name
, out
);
279 if (error
== GIT_SUCCESS
)
282 if (error
< GIT_SUCCESS
)
283 return git__rethrow(error
, "Failed to get value for %s", name
);
287 int git_config_get_string(git_config
*cfg
, const char *name
, const char **out
)
289 file_internal
*internal
;
290 git_config_file
*file
;
291 int error
= GIT_ENOTFOUND
;
294 if (cfg
->files
.length
== 0)
295 return git__throw(GIT_EINVALIDARGS
, "Cannot get variable value; no files open in the `git_config` instance");
297 for (i
= 0; i
< cfg
->files
.length
; ++i
) {
298 internal
= git_vector_get(&cfg
->files
, i
);
299 file
= internal
->file
;
300 if ((error
= file
->get(file
, name
, out
)) == GIT_SUCCESS
)
304 return git__throw(error
, "Config value '%s' not found", name
);
307 int git_config_find_global(char *global_config_path
)
311 home
= getenv("HOME");
315 home
= getenv("USERPROFILE");
319 return git__throw(GIT_EOSERR
, "Failed to open global config file. Cannot locate the user's home directory");
321 git_path_join(global_config_path
, home
, GIT_CONFIG_FILENAME
);
323 if (git_futils_exists(global_config_path
) < GIT_SUCCESS
)
324 return git__throw(GIT_EOSERR
, "Failed to open global config file. The file does not exist");
329 int git_config_open_global(git_config
**out
)
332 char global_path
[GIT_PATH_MAX
];
334 if ((error
= git_config_find_global(global_path
)) < GIT_SUCCESS
)
337 return git_config_open_ondisk(out
, global_path
);