Line Flow Count Block(s) Source
1 - /*
2 - * Copyright (C) the libgit2 contributors. All rights reserved.
3 - *
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.
6 - */
7 -
8 - #include "config.h"
9 -
10 - #include "config_backend.h"
11 - #include "config_parse.h"
12 - #include "config_entries.h"
13 -
14 - typedef struct {
15 - git_config_backend parent;
16 - git_config_entries *entries;
17 - git_buf cfg;
18 - } config_memory_backend;
19 -
20 - typedef struct {
21 - git_config_entries *entries;
22 - git_config_level_t level;
23 - } config_memory_parse_data;
24 -
25 4 2 static int config_error_readonly(void)
26 - {
27 4 2 git_error_set(GIT_ERROR_CONFIG, "this backend is read-only");
28 4 3 return -1;
29 - }
30 -
31 10 2 static int read_variable_cb(
32 - git_config_parser *reader,
33 - const char *current_section,
34 - const char *var_name,
35 - const char *var_value,
36 - const char *line,
37 - size_t line_len,
38 - void *payload)
39 - {
40 10 2 config_memory_parse_data *parse_data = (config_memory_parse_data *) payload;
41 10 2 git_buf buf = GIT_BUF_INIT;
42 - git_config_entry *entry;
43 - const char *c;
44 - int result;
45 -
46 - GIT_UNUSED(reader);
47 - GIT_UNUSED(line);
48 - GIT_UNUSED(line_len);
49 -
50 10 2 if (current_section) {
51 - /* TODO: Once warnings land, we should likely warn
52 - * here. Git appears to warn in most cases if it sees
53 - * un-namespaced config options.
54 - */
55 10 3 git_buf_puts(&buf, current_section);
56 10 4 git_buf_putc(&buf, '.');
57 - }
58 -
59 40 5,7,8 for (c = var_name; *c; c++)
60 30 6 git_buf_putc(&buf, git__tolower(*c));
61 -
62 10 9,10 if (git_buf_oom(&buf))
63 ##### 11 return -1;
64 -
65 10 12 entry = git__calloc(1, sizeof(git_config_entry));
66 10 13,14 GIT_ERROR_CHECK_ALLOC(entry);
67 10 15 entry->name = git_buf_detach(&buf);
68 10 16-18 entry->value = var_value ? git__strdup(var_value) : NULL;
69 10 19 entry->level = parse_data->level;
70 10 19 entry->include_depth = 0;
71 -
72 10 19,20 if ((result = git_config_entries_append(parse_data->entries, entry)) < 0)
73 ##### 21 return result;
74 -
75 10 22 return result;
76 - }
77 -
78 8 2 static int config_memory_open(git_config_backend *backend, git_config_level_t level, const git_repository *repo)
79 - {
80 8 2 config_memory_backend *memory_backend = (config_memory_backend *) backend;
81 8 2 git_config_parser parser = GIT_PARSE_CTX_INIT;
82 - config_memory_parse_data parse_data;
83 - int error;
84 -
85 - GIT_UNUSED(repo);
86 -
87 8 2,3 if ((error = git_config_parser_init(&parser, "in-memory", memory_backend->cfg.ptr,
88 - memory_backend->cfg.size)) < 0)
89 ##### 4 goto out;
90 8 5 parse_data.entries = memory_backend->entries;
91 8 5 parse_data.level = level;
92 -
93 8 5,6 if ((error = git_config_parse(&parser, NULL, read_variable_cb, NULL, NULL, &parse_data)) < 0)
94 1 7 goto out;
95 -
96 - out:
97 8 8 git_config_parser_dispose(&parser);
98 8 9 return error;
99 - }
100 -
101 6 2 static int config_memory_get(git_config_backend *backend, const char *key, git_config_entry **out)
102 - {
103 6 2 config_memory_backend *memory_backend = (config_memory_backend *) backend;
104 6 2 return git_config_entries_get(out, memory_backend->entries, key);
105 - }
106 -
107 2 2 static int config_memory_iterator(
108 - git_config_iterator **iter,
109 - git_config_backend *backend)
110 - {
111 2 2 config_memory_backend *memory_backend = (config_memory_backend *) backend;
112 - git_config_entries *entries;
113 - int error;
114 -
115 2 2,3 if ((error = git_config_entries_dup(&entries, memory_backend->entries)) < 0)
116 ##### 4 goto out;
117 -
118 2 5,6 if ((error = git_config_entries_iterator_new(iter, entries)) < 0)
119 ##### 7 goto out;
120 -
121 - out:
122 - /* Let iterator delete duplicated entries when it's done */
123 2 8 git_config_entries_free(entries);
124 2 9 return error;
125 - }
126 -
127 1 2 static int config_memory_set(git_config_backend *backend, const char *name, const char *value)
128 - {
129 - GIT_UNUSED(backend);
130 - GIT_UNUSED(name);
131 - GIT_UNUSED(value);
132 1 2 return config_error_readonly();
133 - }
134 -
135 ##### 2 static int config_memory_set_multivar(
136 - git_config_backend *backend, const char *name, const char *regexp, const char *value)
137 - {
138 - GIT_UNUSED(backend);
139 - GIT_UNUSED(name);
140 - GIT_UNUSED(regexp);
141 - GIT_UNUSED(value);
142 ##### 2 return config_error_readonly();
143 - }
144 -
145 1 2 static int config_memory_delete(git_config_backend *backend, const char *name)
146 - {
147 - GIT_UNUSED(backend);
148 - GIT_UNUSED(name);
149 1 2 return config_error_readonly();
150 - }
151 -
152 ##### 2 static int config_memory_delete_multivar(git_config_backend *backend, const char *name, const char *regexp)
153 - {
154 - GIT_UNUSED(backend);
155 - GIT_UNUSED(name);
156 - GIT_UNUSED(regexp);
157 ##### 2 return config_error_readonly();
158 - }
159 -
160 1 2 static int config_memory_lock(git_config_backend *backend)
161 - {
162 - GIT_UNUSED(backend);
163 1 2 return config_error_readonly();
164 - }
165 -
166 1 2 static int config_memory_unlock(git_config_backend *backend, int success)
167 - {
168 - GIT_UNUSED(backend);
169 - GIT_UNUSED(success);
170 1 2 return config_error_readonly();
171 - }
172 -
173 8 2 static void config_memory_free(git_config_backend *_backend)
174 - {
175 8 2 config_memory_backend *backend = (config_memory_backend *)_backend;
176 -
177 8 2 if (backend == NULL)
178 8 3,7 return;
179 -
180 8 4 git_config_entries_free(backend->entries);
181 8 5 git_buf_dispose(&backend->cfg);
182 8 6 git__free(backend);
183 - }
184 -
185 8 2 int git_config_backend_from_string(git_config_backend **out, const char *cfg, size_t len)
186 - {
187 - config_memory_backend *backend;
188 -
189 8 2 backend = git__calloc(1, sizeof(config_memory_backend));
190 8 3,4 GIT_ERROR_CHECK_ALLOC(backend);
191 -
192 8 5,6 if (git_config_entries_new(&backend->entries) < 0) {
193 ##### 7 git__free(backend);
194 ##### 8 return -1;
195 - }
196 -
197 8 9,10 if (git_buf_set(&backend->cfg, cfg, len) < 0) {
198 ##### 11 git_config_entries_free(backend->entries);
199 ##### 12 git__free(backend);
200 ##### 13 return -1;
201 - }
202 -
203 8 14 backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
204 8 14 backend->parent.readonly = 1;
205 8 14 backend->parent.open = config_memory_open;
206 8 14 backend->parent.get = config_memory_get;
207 8 14 backend->parent.set = config_memory_set;
208 8 14 backend->parent.set_multivar = config_memory_set_multivar;
209 8 14 backend->parent.del = config_memory_delete;
210 8 14 backend->parent.del_multivar = config_memory_delete_multivar;
211 8 14 backend->parent.iterator = config_memory_iterator;
212 8 14 backend->parent.lock = config_memory_lock;
213 8 14 backend->parent.unlock = config_memory_unlock;
214 8 14 backend->parent.snapshot = git_config_backend_snapshot;
215 8 14 backend->parent.free = config_memory_free;
216 -
217 8 14 *out = (git_config_backend *)backend;
218 -
219 8 14 return 0;
220 - }