Skip to content

Commit 3a82475

Browse files
committed
config_file: add list holding config entries in order of appearance
Right now, we only keep all configuration entries in a string map. This is required to efficiently access configuration entries by keys. It has the disadvantage of not being able to iterate through configuration entries in the order they were read, though. Instead, we only iterate through entries in a seemingly random order. Extend `diskfile_entries` by another list holding configuration entries. Like this, we maintain all entries in two data structures and can use the required one based on the current use case.
1 parent 8c0b071 commit 3a82475

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

src/config_file.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ typedef struct git_config_file_iter {
4040
typedef struct {
4141
git_atomic refcount;
4242
git_strmap *map;
43+
config_entry_list *list;
4344
} diskfile_entries;
4445

4546
typedef struct {
@@ -129,6 +130,19 @@ int git_config_file_normalize_section(char *start, char *end)
129130
return 0;
130131
}
131132

133+
static void config_entry_list_append(config_entry_list **list, config_entry_list *entry)
134+
{
135+
config_entry_list *head = *list;
136+
137+
if (head) {
138+
while (head->next != NULL)
139+
head = head->next;
140+
head->next = entry;
141+
} else {
142+
*list = entry;
143+
}
144+
}
145+
132146
/* Add or append the new config option */
133147
static int diskfile_entries_append(diskfile_entries *entries, git_config_entry *entry)
134148
{
@@ -143,23 +157,25 @@ static int diskfile_entries_append(diskfile_entries *entries, git_config_entry *
143157
pos = git_strmap_lookup_index(entries->map, entry->name);
144158
if (!git_strmap_valid_index(entries->map, pos)) {
145159
git_strmap_insert(entries->map, entry->name, var, &error);
160+
161+
if (error > 0)
162+
error = 0;
146163
} else {
147164
existing = git_strmap_value_at(entries->map, pos);
148-
while (existing->next != NULL) {
149-
existing = existing->next;
150-
}
151-
existing->next = var;
165+
config_entry_list_append(&existing, var);
152166
}
153167

154-
if (error > 0)
155-
error = 0;
168+
var = git__calloc(1, sizeof(config_entry_list));
169+
GITERR_CHECK_ALLOC(var);
170+
var->entry = entry;
171+
config_entry_list_append(&entries->list, var);
156172

157173
return error;
158174
}
159175

160176
static void diskfile_entries_free(diskfile_entries *entries)
161177
{
162-
config_entry_list *list = NULL;
178+
config_entry_list *list = NULL, *next;
163179

164180
if (!entries)
165181
return;
@@ -169,6 +185,14 @@ static void diskfile_entries_free(diskfile_entries *entries)
169185

170186
git_strmap_foreach_value(entries->map, list, config_entry_list_free(list));
171187
git_strmap_free(entries->map);
188+
189+
list = entries->list;
190+
while (list != NULL) {
191+
next = list->next;
192+
git__free(list);
193+
list = next;
194+
}
195+
172196
git__free(entries);
173197
}
174198

0 commit comments

Comments
 (0)