source src/config_mem.c
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 | - | } |