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_entries.h"
9 -
10 - typedef struct config_entry_list {
11 - struct config_entry_list *next;
12 - struct config_entry_list *last;
13 - git_config_entry *entry;
14 - bool first;
15 - } config_entry_list;
16 -
17 - typedef struct config_entries_iterator {
18 - git_config_iterator parent;
19 - git_config_entries *entries;
20 - config_entry_list *head;
21 - } config_entries_iterator;
22 -
23 - struct git_config_entries {
24 - git_refcount rc;
25 - git_strmap *map;
26 - config_entry_list *list;
27 - };
28 -
29 122238 2 int git_config_entries_new(git_config_entries **out)
30 - {
31 - git_config_entries *entries;
32 - int error;
33 -
34 122238 2 entries = git__calloc(1, sizeof(git_config_entries));
35 122247 3,4 GIT_ERROR_CHECK_ALLOC(entries);
36 122247 5 GIT_REFCOUNT_INC(entries);
37 -
38 122270 6,7 if ((error = git_strmap_new(&entries->map)) < 0)
39 ##### 8 git__free(entries);
40 - else
41 122250 9 *out = entries;
42 -
43 122252 10 return error;
44 - }
45 -
46 317179 2 int git_config_entries_dup_entry(git_config_entries *entries, const git_config_entry *entry)
47 - {
48 - git_config_entry *duplicated;
49 - int error;
50 -
51 317179 2 duplicated = git__calloc(1, sizeof(git_config_entry));
52 317311 3,4 GIT_ERROR_CHECK_ALLOC(duplicated);
53 -
54 317311 5 duplicated->name = git__strdup(entry->name);
55 317345 6,7 GIT_ERROR_CHECK_ALLOC(duplicated->name);
56 -
57 317345 8 if (entry->value) {
58 317341 9 duplicated->value = git__strdup(entry->value);
59 317342 10,11 GIT_ERROR_CHECK_ALLOC(duplicated->value);
60 - }
61 317346 12 duplicated->level = entry->level;
62 317346 12 duplicated->include_depth = entry->include_depth;
63 -
64 317346 12,13 if ((error = git_config_entries_append(entries, duplicated)) < 0)
65 ##### 14 goto out;
66 -
67 - out:
68 317237 15,16 if (error && duplicated) {
69 ##### 17 git__free((char *) duplicated->name);
70 ##### 18 git__free((char *) duplicated->value);
71 ##### 19 git__free(duplicated);
72 - }
73 317237 20 return error;
74 - }
75 -
76 52398 2 int git_config_entries_dup(git_config_entries **out, git_config_entries *entries)
77 - {
78 52398 2 git_config_entries *result = NULL;
79 - config_entry_list *head;
80 - int error;
81 -
82 52398 2,3 if ((error = git_config_entries_new(&result)) < 0)
83 ##### 4 goto out;
84 -
85 220406 5,9,10 for (head = entries->list; head; head = head->next)
86 168020 6,7 if ((git_config_entries_dup_entry(result, head->entry)) < 0)
87 ##### 8 goto out;
88 -
89 52386 11 *out = result;
90 52386 11 result = NULL;
91 -
92 - out:
93 52386 12 git_config_entries_free(result);
94 52385 13 return error;
95 - }
96 -
97 348502 2 void git_config_entries_incref(git_config_entries *entries)
98 - {
99 348502 2 GIT_REFCOUNT_INC(entries);
100 348533 3 }
101 -
102 122264 2 static void config_entries_free(git_config_entries *entries)
103 - {
104 122264 2 config_entry_list *list = NULL, *next;
105 -
106 122264 2 git_strmap_free(entries->map);
107 -
108 122233 3 list = entries->list;
109 537649 3,10 while (list != NULL) {
110 415376 4 next = list->next;
111 415376 4 if (list->first)
112 414910 5 git__free((char *) list->entry->name);
113 415393 6 git__free((char *) list->entry->value);
114 415410 7 git__free(list->entry);
115 415410 8 git__free(list);
116 415416 9 list = next;
117 - }
118 -
119 122273 11 git__free(entries);
120 122262 12 }
121 -
122 - 2 suppressed: function cannot be solved git_config_entries_free (automatic due to inconsistent arc counts in .gcda files)void git_config_entries_free(git_config_entries *entries)
123 - {
124 - 2 suppressed: function cannot be solved git_config_entries_free (automatic due to inconsistent arc counts in .gcda files) if (entries)
125 - 3-6 suppressed: function cannot be solved git_config_entries_free (automatic due to inconsistent arc counts in .gcda files) GIT_REFCOUNT_DEC(entries, config_entries_free);
126 - 7 suppressed: function cannot be solved git_config_entries_free (automatic due to inconsistent arc counts in .gcda files)}
127 -
128 415311 2 int git_config_entries_append(git_config_entries *entries, git_config_entry *entry)
129 - {
130 - config_entry_list *existing, *head;
131 -
132 415311 2 head = git__calloc(1, sizeof(config_entry_list));
133 415335 3,4 GIT_ERROR_CHECK_ALLOC(head);
134 415335 5 head->entry = entry;
135 -
136 - /*
137 - * This is a micro-optimization for configuration files
138 - * with a lot of same keys. As for multivars the entry's
139 - * key will be the same for all entries, we can just free
140 - * all except the first entry's name and just re-use it.
141 - */
142 415335 5,6 if ((existing = git_strmap_get(entries->map, entry->name)) != NULL) {
143 484 7 git__free((char *) entry->name);
144 670 8 entry->name = existing->entry->name;
145 - } else {
146 414653 9 head->first = 1;
147 - }
148 -
149 415323 10 if (entries->list)
150 323056 11 entries->list->last->next = head;
151 - else
152 92267 12 entries->list = head;
153 415323 13 entries->list->last = head;
154 -
155 415323 13,14 if (git_strmap_set(entries->map, entry->name, head) < 0)
156 ##### 15 return -1;
157 -
158 415226 16 return 0;
159 - }
160 -
161 237033 2 int git_config_entries_get(git_config_entry **out, git_config_entries *entries, const char *key)
162 - {
163 - config_entry_list *entry;
164 237033 2,3 if ((entry = git_strmap_get(entries->map, key)) == NULL)
165 214528 4 return GIT_ENOTFOUND;
166 22443 5 *out = entry->entry;
167 22443 5 return 0;
168 - }
169 -
170 10640 2 int git_config_entries_get_unique(git_config_entry **out, git_config_entries *entries, const char *key)
171 - {
172 - config_entry_list *entry;
173 -
174 10640 2,3 if ((entry = git_strmap_get(entries->map, key)) == NULL)
175 6100 4 return GIT_ENOTFOUND;
176 -
177 4540 5 if (!entry->first) {
178 ##### 6 git_error_set(GIT_ERROR_CONFIG, "entry is not unique due to being a multivar");
179 ##### 7 return -1;
180 - }
181 -
182 4540 8 if (entry->entry->include_depth) {
183 2 9 git_error_set(GIT_ERROR_CONFIG, "entry is not unique due to being included");
184 2 10 return -1;
185 - }
186 -
187 4538 11 *out = entry->entry;
188 -
189 4538 11 return 0;
190 - }
191 -
192 52390 2 static void config_iterator_free(git_config_iterator *iter)
193 - {
194 52390 2 config_entries_iterator *it = (config_entries_iterator *) iter;
195 52390 2 git_config_entries_free(it->entries);
196 52396 3 git__free(it);
197 52398 4 }
198 -
199 220376 2 static int config_iterator_next(
200 - git_config_entry **entry,
201 - git_config_iterator *iter)
202 - {
203 220376 2 config_entries_iterator *it = (config_entries_iterator *) iter;
204 -
205 220376 2 if (!it->head)
206 52376 3 return GIT_ITEROVER;
207 -
208 168000 4 *entry = it->head->entry;
209 168000 4 it->head = it->head->next;
210 -
211 168000 4 return 0;
212 - }
213 -
214 52384 2 int git_config_entries_iterator_new(git_config_iterator **out, git_config_entries *entries)
215 - {
216 - config_entries_iterator *it;
217 -
218 52384 2 it = git__calloc(1, sizeof(config_entries_iterator));
219 52395 3,4 GIT_ERROR_CHECK_ALLOC(it);
220 52395 5 it->parent.next = config_iterator_next;
221 52395 5 it->parent.free = config_iterator_free;
222 52395 5 it->head = entries->list;
223 52395 5 it->entries = entries;
224 -
225 52395 5 git_config_entries_incref(entries);
226 52400 6 *out = &it->parent;
227 -
228 52400 6 return 0;
229 - }