From 49624d1e518f14fe03ba6c8824aaaf420e01a834 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 24 Feb 2017 12:43:35 -0800 Subject: [PATCH 1/4] refs: parse_hide_refs_config to use parse_config_key parse_config_key was introduced in 1b86bbb0ade (config: add helper function for parsing key names, 2013-01-22), the NEEDSWORK that is removed in this patch was introduced at daebaa7813 (upload/receive-pack: allow hiding ref hierarchies, 2013-01-18), which is only a couple days apart, so presumably the code replaced in this patch was only introduced due to not wanting to wait on the proper helper function being available. Make the condition easier to read by using parse_config_key. Signed-off-by: Stefan Beller Reviewed-by: Jeff King Signed-off-by: Junio C Hamano --- refs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/refs.c b/refs.c index 9bd0bc177b..92f800e9cd 100644 --- a/refs.c +++ b/refs.c @@ -1029,10 +1029,11 @@ static struct string_list *hide_refs; int parse_hide_refs_config(const char *var, const char *value, const char *section) { + const char *subsection, *key; + int subsection_len; if (!strcmp("transfer.hiderefs", var) || - /* NEEDSWORK: use parse_config_key() once both are merged */ - (starts_with(var, section) && var[strlen(section)] == '.' && - !strcmp(var + strlen(section), ".hiderefs"))) { + (!parse_config_key(var, section, &subsection, &subsection_len, &key) + && !subsection && !strcmp(key, "hiderefs"))) { char *ref; int len; From e3394fdce79411fd51e20082c0faf7061007bc1c Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 24 Feb 2017 16:07:19 -0500 Subject: [PATCH 2/4] parse_config_key: use skip_prefix instead of starts_with This saves us having to repeatedly add in "section_len" (and also avoids walking over the first part of the string multiple times for a strlen() and strrchr()). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- config.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/config.c b/config.c index 617b2e3cf4..a23f260792 100644 --- a/config.c +++ b/config.c @@ -2531,11 +2531,10 @@ int parse_config_key(const char *var, const char **subsection, int *subsection_len, const char **key) { - int section_len = strlen(section); const char *dot; /* Does it start with "section." ? */ - if (!starts_with(var, section) || var[section_len] != '.') + if (!skip_prefix(var, section, &var) || *var != '.') return -1; /* @@ -2547,12 +2546,12 @@ int parse_config_key(const char *var, *key = dot + 1; /* Did we have a subsection at all? */ - if (dot == var + section_len) { + if (dot == var) { *subsection = NULL; *subsection_len = 0; } else { - *subsection = var + section_len + 1; + *subsection = var + 1; *subsection_len = dot - *subsection; } From 48f8d9f7323d0927cd955f129babbf93eda50473 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 24 Feb 2017 16:08:02 -0500 Subject: [PATCH 3/4] parse_config_key: allow matching single-level config The parse_config_key() function was introduced to make it easier to match "section.subsection.key" variables. It also handles the simpler "section.key", and the caller is responsible for distinguishing the two from its out-parameters. Most callers who _only_ want "section.key" would just use a strcmp(var, "section.key"), since there is no parsing required. However, they may still use parse_config_key() if their "section" variable isn't a constant (an example of this is in parse_hide_refs_config). Using the parse_config_key is a bit clunky, though: const char *subsection; int subsection_len; const char *key; if (!parse_config_key(var, section, &subsection, &subsection_len, &key) && !subsection) { /* matched! */ } Instead, let's treat a NULL subsection as an indication that the caller does not expect one. That lets us write: const char *key; if (!parse_config_key(var, section, NULL, NULL, &key)) { /* matched! */ } Existing callers should be unaffected, as passing a NULL subsection would currently segfault. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 5 ++++- config.c | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cache.h b/cache.h index 5c035dae57..e7b0e6be95 100644 --- a/cache.h +++ b/cache.h @@ -1790,8 +1790,11 @@ extern int git_config_include(const char *name, const char *value, void *data); * * (i.e., what gets handed to a config_fn_t). The caller provides the section; * we return -1 if it does not match, 0 otherwise. The subsection and key - * out-parameters are filled by the function (and subsection is NULL if it is + * out-parameters are filled by the function (and *subsection is NULL if it is * missing). + * + * If the subsection pointer-to-pointer passed in is NULL, returns 0 only if + * there is no subsection at all. */ extern int parse_config_key(const char *var, const char *section, diff --git a/config.c b/config.c index a23f260792..fd92738fba 100644 --- a/config.c +++ b/config.c @@ -2547,10 +2547,14 @@ int parse_config_key(const char *var, /* Did we have a subsection at all? */ if (dot == var) { - *subsection = NULL; - *subsection_len = 0; + if (subsection) { + *subsection = NULL; + *subsection_len = 0; + } } else { + if (!subsection) + return -1; *subsection = var + 1; *subsection_len = dot - *subsection; } From ad8c7cdadd96c66d0adf894250c8f4dd77bb2bee Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 24 Feb 2017 16:08:16 -0500 Subject: [PATCH 4/4] parse_hide_refs_config: tell parse_config_key we don't want a subsection This lets us avoid declaring some otherwise useless variables. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- refs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/refs.c b/refs.c index 92f800e9cd..cb81245579 100644 --- a/refs.c +++ b/refs.c @@ -1029,11 +1029,10 @@ static struct string_list *hide_refs; int parse_hide_refs_config(const char *var, const char *value, const char *section) { - const char *subsection, *key; - int subsection_len; + const char *key; if (!strcmp("transfer.hiderefs", var) || - (!parse_config_key(var, section, &subsection, &subsection_len, &key) - && !subsection && !strcmp(key, "hiderefs"))) { + (!parse_config_key(var, section, NULL, NULL, &key) && + !strcmp(key, "hiderefs"))) { char *ref; int len;