Skip to content

Commit 271e5fb

Browse files
committed
config_file: duplicate accessors for readonly backend
While most functions of the readonly configuration backend are implemented separately from the writeable configuration backend, the two functions `config_iterator_new` and `config_get` are shared between both. This sharing makes it necessary to have some shared data structures, which is the `diskfile_header` structure. Unfortunately, this makes the backends harder to grasp than necessary due to all the casting between structs and also quite error prone. Reimplement those functions for the readonly backends. As readonly backends cannot be refreshed anyway, we can remove the calls to `config_refresh` in there.
1 parent 4e7ce1f commit 271e5fb

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

src/config_file.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,25 @@ static int config_iterator_new(
284284
return error;
285285
}
286286

287+
static int config_iterator_new_readonly(
288+
git_config_iterator **iter,
289+
struct git_config_backend *backend)
290+
{
291+
diskfile_header *bh = GIT_CONTAINER_OF(backend, diskfile_header, parent);
292+
git_config_entries *entries = NULL;
293+
int error;
294+
295+
if ((error = git_config_entries_dup(&entries, bh->entries)) < 0 ||
296+
(error = git_config_entries_iterator_new(iter, entries)) < 0)
297+
goto out;
298+
299+
out:
300+
/* Let iterator delete duplicated entries when it's done */
301+
git_config_entries_free(entries);
302+
return error;
303+
}
304+
305+
287306
static int config_set(git_config_backend *cfg, const char *name, const char *value)
288307
{
289308
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
@@ -361,6 +380,28 @@ static int config_get(git_config_backend *cfg, const char *key, git_config_entry
361380
return 0;
362381
}
363382

383+
static int config_get_readonly(git_config_backend *cfg, const char *key, git_config_entry **out)
384+
{
385+
diskfile_header *h = GIT_CONTAINER_OF(cfg, diskfile_header, parent);
386+
git_config_entries *entries = NULL;
387+
git_config_entry *entry;
388+
int error = 0;
389+
390+
if ((entries = diskfile_entries_take(h)) == NULL)
391+
return -1;
392+
393+
if ((error = (git_config_entries_get(&entry, entries, key))) < 0) {
394+
git_config_entries_free(entries);
395+
return error;
396+
}
397+
398+
entry->free = free_diskfile_entry;
399+
entry->payload = entries;
400+
*out = entry;
401+
402+
return 0;
403+
}
404+
364405
static int config_set_multivar(
365406
git_config_backend *cfg, const char *name, const char *regexp, const char *value)
366407
{
@@ -642,12 +683,12 @@ static int config_snapshot(git_config_backend **out, git_config_backend *source)
642683
backend->header.parent.readonly = 1;
643684
backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
644685
backend->header.parent.open = config_readonly_open;
645-
backend->header.parent.get = config_get;
686+
backend->header.parent.get = config_get_readonly;
646687
backend->header.parent.set = config_set_readonly;
647688
backend->header.parent.set_multivar = config_set_multivar_readonly;
648689
backend->header.parent.del = config_delete_readonly;
649690
backend->header.parent.del_multivar = config_delete_multivar_readonly;
650-
backend->header.parent.iterator = config_iterator_new;
691+
backend->header.parent.iterator = config_iterator_new_readonly;
651692
backend->header.parent.lock = config_lock_readonly;
652693
backend->header.parent.unlock = config_unlock_readonly;
653694
backend->header.parent.free = backend_readonly_free;

0 commit comments

Comments
 (0)