diff --git a/src/libgit2/config_backend.h b/src/libgit2/config_backend.h index dbb190514..677b2236f 100644 --- a/src/libgit2/config_backend.h +++ b/src/libgit2/config_backend.h @@ -38,13 +38,19 @@ extern int git_config_backend_from_file(git_config_backend **out, const char *pa extern int git_config_backend_snapshot(git_config_backend **out, git_config_backend *source); /** - * Create an in-memory configuration file backend + * Create an in-memory configuration file backend from a string in standard + * git configuration file format. * * @param out the new backend + * @param origin the name of the origin to use (or NULL for "memory") * @param cfg the configuration that is to be parsed * @param len the length of the string pointed to by `cfg` */ -extern int git_config_backend_from_string(git_config_backend **out, const char *cfg, size_t len); +extern int git_config_backend_from_string( + git_config_backend **out, + const char *origin, + const char *cfg, + size_t len); GIT_INLINE(int) git_config_backend_open(git_config_backend *cfg, unsigned int level, const git_repository *repo) { diff --git a/src/libgit2/config_file.c b/src/libgit2/config_file.c index c86e98bf2..340e85691 100644 --- a/src/libgit2/config_file.c +++ b/src/libgit2/config_file.c @@ -803,11 +803,13 @@ static int read_on_variable( GIT_ERROR_CHECK_ALLOC(entry->base.value); } - entry->base.origin_path = git_config_list_add_path(parse_data->config_list, parse_data->file->path); + entry->base.backend_type = git_config_list_add_string(parse_data->config_list, CONFIG_FILE_TYPE); + GIT_ERROR_CHECK_ALLOC(entry->base.backend_type); + + entry->base.origin_path = git_config_list_add_string(parse_data->config_list, parse_data->file->path); GIT_ERROR_CHECK_ALLOC(entry->base.origin_path); entry->base.level = parse_data->level; - entry->base.backend_type = CONFIG_FILE_TYPE; entry->base.include_depth = parse_data->depth; entry->base.free = git_config_list_entry_free; entry->config_list = parse_data->config_list; diff --git a/src/libgit2/config_list.c b/src/libgit2/config_list.c index f642c87a4..0b7a4f360 100644 --- a/src/libgit2/config_list.c +++ b/src/libgit2/config_list.c @@ -27,8 +27,8 @@ typedef struct config_list_iterator { struct git_config_list { git_refcount rc; - /* Paths to config files that contribute to these entries */ - git_strmap *paths; + /* Interned strings - paths to config files or backend types */ + git_strmap *strings; /* Config entries */ git_strmap *map; @@ -43,9 +43,9 @@ int git_config_list_new(git_config_list **out) GIT_ERROR_CHECK_ALLOC(config_list); GIT_REFCOUNT_INC(config_list); - if (git_strmap_new(&config_list->paths) < 0 || + if (git_strmap_new(&config_list->strings) < 0 || git_strmap_new(&config_list->map) < 0) { - git_strmap_free(config_list->paths); + git_strmap_free(config_list->strings); git_strmap_free(config_list->map); git__free(config_list); @@ -72,12 +72,14 @@ int git_config_list_dup_entry(git_config_list *config_list, const git_config_ent GIT_ERROR_CHECK_ALLOC(duplicated->base.value); } + duplicated->base.backend_type = git_config_list_add_string(config_list, entry->backend_type); + GIT_ERROR_CHECK_ALLOC(duplicated->base.backend_type); + if (entry->origin_path) { - duplicated->base.origin_path = git_config_list_add_path(config_list, entry->origin_path); + duplicated->base.origin_path = git_config_list_add_string(config_list, entry->origin_path); GIT_ERROR_CHECK_ALLOC(duplicated->base.origin_path); } - duplicated->base.backend_type = entry->backend_type; duplicated->base.level = entry->level; duplicated->base.include_depth = entry->include_depth; duplicated->base.free = git_config_list_entry_free; @@ -125,12 +127,12 @@ static void config_list_free(git_config_list *config_list) { config_entry_list *entry_list = NULL, *next; config_entry_map_head *head; - char *path; + char *str; - git_strmap_foreach_value(config_list->paths, path, { - git__free(path); + git_strmap_foreach_value(config_list->strings, str, { + git__free(str); }); - git_strmap_free(config_list->paths); + git_strmap_free(config_list->strings); git_strmap_foreach_value(config_list->map, head, { git__free((char *) head->entry->base.name); @@ -269,18 +271,18 @@ void git_config_list_entry_free(git_config_entry *e) git_config_list_free(entry->config_list); } -const char *git_config_list_add_path( +const char *git_config_list_add_string( git_config_list *config_list, - const char *path) + const char *str) { - const char *p; + const char *s; - if ((p = git_strmap_get(config_list->paths, path)) != NULL) - return p; + if ((s = git_strmap_get(config_list->strings, str)) != NULL) + return s; - if ((p = git__strdup(path)) == NULL || - git_strmap_set(config_list->paths, p, (void *)p) < 0) + if ((s = git__strdup(str)) == NULL || + git_strmap_set(config_list->strings, s, (void *)s) < 0) return NULL; - return p; + return s; } diff --git a/src/libgit2/config_list.h b/src/libgit2/config_list.h index 83c43b9a0..023bca1e5 100644 --- a/src/libgit2/config_list.h +++ b/src/libgit2/config_list.h @@ -27,6 +27,6 @@ int git_config_list_append(git_config_list *list, git_config_list_entry *entry); int git_config_list_get(git_config_list_entry **out, git_config_list *list, const char *key); int git_config_list_get_unique(git_config_list_entry **out, git_config_list *list, const char *key); int git_config_list_iterator_new(git_config_iterator **out, git_config_list *list); -const char *git_config_list_add_path(git_config_list *list, const char *path); +const char *git_config_list_add_string(git_config_list *list, const char *str); void git_config_list_entry_free(git_config_entry *entry); diff --git a/src/libgit2/config_mem.c b/src/libgit2/config_mem.c index 748a14716..8faa53dcb 100644 --- a/src/libgit2/config_mem.c +++ b/src/libgit2/config_mem.c @@ -13,11 +13,13 @@ typedef struct { git_config_backend parent; + char *type; git_config_list *config_list; git_str cfg; } config_memory_backend; typedef struct { + const char *backend_type; git_config_list *config_list; git_config_level_t level; } config_memory_parse_data; @@ -68,7 +70,7 @@ static int read_variable_cb( entry->base.value = var_value ? git__strdup(var_value) : NULL; entry->base.level = parse_data->level; entry->base.include_depth = 0; - entry->base.backend_type = "memory"; + entry->base.backend_type = parse_data->backend_type; entry->base.free = git_config_list_entry_free; entry->config_list = parse_data->config_list; @@ -90,6 +92,9 @@ static int config_memory_open(git_config_backend *backend, git_config_level_t le if ((error = git_config_parser_init(&parser, "in-memory", memory_backend->cfg.ptr, memory_backend->cfg.size)) < 0) goto out; + + parse_data.backend_type = git_config_list_add_string( + memory_backend->config_list, memory_backend->type); parse_data.config_list = memory_backend->config_list; parse_data.level = level; @@ -187,12 +192,17 @@ static void config_memory_free(git_config_backend *_backend) if (backend == NULL) return; + git__free(backend->type); git_config_list_free(backend->config_list); git_str_dispose(&backend->cfg); git__free(backend); } -int git_config_backend_from_string(git_config_backend **out, const char *cfg, size_t len) +int git_config_backend_from_string( + git_config_backend **out, + const char *backend_type, + const char *cfg, + size_t len) { config_memory_backend *backend; @@ -210,6 +220,9 @@ int git_config_backend_from_string(git_config_backend **out, const char *cfg, si return -1; } + backend->type = git__strdup(backend_type ? backend_type : "in-memory"); + GIT_ERROR_CHECK_ALLOC(backend->type); + backend->parent.version = GIT_CONFIG_BACKEND_VERSION; backend->parent.readonly = 1; backend->parent.open = config_memory_open; diff --git a/tests/libgit2/config/memory.c b/tests/libgit2/config/memory.c index ae661899d..67a61a1c5 100644 --- a/tests/libgit2/config/memory.c +++ b/tests/libgit2/config/memory.c @@ -61,7 +61,7 @@ static void assert_config_contains_all(git_config_backend *backend, static void setup_backend(const char *cfg) { - cl_git_pass(git_config_backend_from_string(&backend, cfg, strlen(cfg))); + cl_git_pass(git_config_backend_from_string(&backend, "test", cfg, strlen(cfg))); cl_git_pass(git_config_backend_open(backend, 0, NULL)); } @@ -88,7 +88,7 @@ void test_config_memory__malformed_fails_to_open(void) const char *cfg = "[general\n" "foo=bar\n"; - cl_git_pass(git_config_backend_from_string(&backend, cfg, strlen(cfg))); + cl_git_pass(git_config_backend_from_string(&backend, "test", cfg, strlen(cfg))); cl_git_fail(git_config_backend_open(backend, 0, NULL)); } diff --git a/tests/libgit2/config/snapshot.c b/tests/libgit2/config/snapshot.c index bfb68e21e..87a68600e 100644 --- a/tests/libgit2/config/snapshot.c +++ b/tests/libgit2/config/snapshot.c @@ -153,7 +153,7 @@ void test_config_snapshot__snapshot_from_in_memory(void) int i; cl_git_pass(git_config_new(&cfg)); - cl_git_pass(git_config_backend_from_string(&backend, configuration, strlen(configuration))); + cl_git_pass(git_config_backend_from_string(&backend, "test", configuration, strlen(configuration))); cl_git_pass(git_config_add_backend(cfg, backend, 0, NULL, 0)); cl_git_pass(git_config_snapshot(&snapshot, cfg)); @@ -165,7 +165,7 @@ void test_config_snapshot__snapshot_from_in_memory(void) cl_assert_equal_s("section.key", entry->name); cl_assert_equal_s("1", entry->value); - cl_assert_equal_s("memory", entry->backend_type); + cl_assert_equal_s("test", entry->backend_type); cl_assert_equal_p(NULL, entry->origin_path); git_config_entry_free(entry);