config: move a few helper functions up

git_config_parse_key() implements the validation and downcasing of <section> and <variable> in "<section>[.<subsection>].<variable>" configuration variable name. Move it (and helpers it uses) a bit up so that it can be used by git_config_parse_parameter(), which is used to check configuration settings that are given on the command line (i.e. "git -c VAR=VAL cmd"), in a later patch. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Feb 23, 2017 at 14:44 UTC ee98df3fa41d83f037b96cb11dc72181816920c7
1 file changed +92 -92
config.c
+92 -92
@@ -199,6 +199,98 @@ void git_config_push_parameter(const char *text)
199 strbuf_release(&env);
200 }
201
202 +static inline int iskeychar(int c)
203 +{
204 + return isalnum(c) || c == '-';
205 +}
206 +
207 +/*
208 + * Auxiliary function to sanity-check and split the key into the section
209 + * identifier and variable name.
210 + *
211 + * Returns 0 on success, -1 when there is an invalid character in the key and
212 + * -2 if there is no section name in the key.
213 + *
214 + * store_key - pointer to char* which will hold a copy of the key with
215 + * lowercase section and variable name
216 + * baselen - pointer to int which will hold the length of the
217 + * section + subsection part, can be NULL
218 + */
219 +static int git_config_parse_key_1(const char *key, char **store_key, int *baselen_, int quiet)
220 +{
221 + int i, dot, baselen;
222 + const char *last_dot = strrchr(key, '.');
223 +
224 + /*
225 + * Since "key" actually contains the section name and the real
226 + * key name separated by a dot, we have to know where the dot is.
227 + */
228 +
229 + if (last_dot == NULL || last_dot == key) {
230 + if (!quiet)
231 + error("key does not contain a section: %s", key);
232 + return -CONFIG_NO_SECTION_OR_NAME;
233 + }
234 +
235 + if (!last_dot[1]) {
236 + if (!quiet)
237 + error("key does not contain variable name: %s", key);
238 + return -CONFIG_NO_SECTION_OR_NAME;
239 + }
240 +
241 + baselen = last_dot - key;
242 + if (baselen_)
243 + *baselen_ = baselen;
244 +
245 + /*
246 + * Validate the key and while at it, lower case it for matching.
247 + */
248 + if (store_key)
249 + *store_key = xmallocz(strlen(key));
250 +
251 + dot = 0;
252 + for (i = 0; key[i]; i++) {
253 + unsigned char c = key[i];
254 + if (c == '.')
255 + dot = 1;
256 + /* Leave the extended basename untouched.. */
257 + if (!dot || i > baselen) {
258 + if (!iskeychar(c) ||
259 + (i == baselen + 1 && !isalpha(c))) {
260 + if (!quiet)
261 + error("invalid key: %s", key);
262 + goto out_free_ret_1;
263 + }
264 + c = tolower(c);
265 + } else if (c == '\n') {
266 + if (!quiet)
267 + error("invalid key (newline): %s", key);
268 + goto out_free_ret_1;
269 + }
270 + if (store_key)
271 + (*store_key)[i] = c;
272 + }
273 +
274 + return 0;
275 +
276 +out_free_ret_1:
277 + if (store_key) {
278 + free(*store_key);
279 + *store_key = NULL;
280 + }
281 + return -CONFIG_INVALID_KEY;
282 +}
283 +
284 +int git_config_parse_key(const char *key, char **store_key, int *baselen)
285 +{
286 + return git_config_parse_key_1(key, store_key, baselen, 0);
287 +}
288 +
289 +int git_config_key_is_valid(const char *key)
290 +{
291 + return !git_config_parse_key_1(key, NULL, NULL, 1);
292 +}
293 +
294 int git_config_parse_parameter(const char *text,
295 config_fn_t fn, void *data)
296 {
@@ -354,11 +446,6 @@ static char *parse_value(void)
446 }
447 }
448
357 -static inline int iskeychar(int c)
358 -{
359 - return isalnum(c) || c == '-';
360 -}
361 -
449 static int get_value(config_fn_t fn, void *data, struct strbuf *name)
450 {
451 int c;
@@ -1962,93 +2049,6 @@ void git_config_set(const char *key, const char *value)
2049 git_config_set_multivar(key, value, NULL, 0);
2050 }
2051
1965 -/*
1966 - * Auxiliary function to sanity-check and split the key into the section
1967 - * identifier and variable name.
1968 - *
1969 - * Returns 0 on success, -1 when there is an invalid character in the key and
1970 - * -2 if there is no section name in the key.
1971 - *
1972 - * store_key - pointer to char* which will hold a copy of the key with
1973 - * lowercase section and variable name
1974 - * baselen - pointer to int which will hold the length of the
1975 - * section + subsection part, can be NULL
1976 - */
1977 -static int git_config_parse_key_1(const char *key, char **store_key, int *baselen_, int quiet)
1978 -{
1979 - int i, dot, baselen;
1980 - const char *last_dot = strrchr(key, '.');
1981 -
1982 - /*
1983 - * Since "key" actually contains the section name and the real
1984 - * key name separated by a dot, we have to know where the dot is.
1985 - */
1986 -
1987 - if (last_dot == NULL || last_dot == key) {
1988 - if (!quiet)
1989 - error("key does not contain a section: %s", key);
1990 - return -CONFIG_NO_SECTION_OR_NAME;
1991 - }
1992 -
1993 - if (!last_dot[1]) {
1994 - if (!quiet)
1995 - error("key does not contain variable name: %s", key);
1996 - return -CONFIG_NO_SECTION_OR_NAME;
1997 - }
1998 -
1999 - baselen = last_dot - key;
2000 - if (baselen_)
2001 - *baselen_ = baselen;
2002 -
2003 - /*
2004 - * Validate the key and while at it, lower case it for matching.
2005 - */
2006 - if (store_key)
2007 - *store_key = xmallocz(strlen(key));
2008 -
2009 - dot = 0;
2010 - for (i = 0; key[i]; i++) {
2011 - unsigned char c = key[i];
2012 - if (c == '.')
2013 - dot = 1;
2014 - /* Leave the extended basename untouched.. */
2015 - if (!dot || i > baselen) {
2016 - if (!iskeychar(c) ||
2017 - (i == baselen + 1 && !isalpha(c))) {
2018 - if (!quiet)
2019 - error("invalid key: %s", key);
2020 - goto out_free_ret_1;
2021 - }
2022 - c = tolower(c);
2023 - } else if (c == '\n') {
2024 - if (!quiet)
2025 - error("invalid key (newline): %s", key);
2026 - goto out_free_ret_1;
2027 - }
2028 - if (store_key)
2029 - (*store_key)[i] = c;
2030 - }
2031 -
2032 - return 0;
2033 -
2034 -out_free_ret_1:
2035 - if (store_key) {
2036 - free(*store_key);
2037 - *store_key = NULL;
2038 - }
2039 - return -CONFIG_INVALID_KEY;
2040 -}
2041 -
2042 -int git_config_parse_key(const char *key, char **store_key, int *baselen)
2043 -{
2044 - return git_config_parse_key_1(key, store_key, baselen, 0);
2045 -}
2046 -
2047 -int git_config_key_is_valid(const char *key)
2048 -{
2049 - return !git_config_parse_key_1(key, NULL, NULL, 1);
2050 -}
2051 -
2052 /*
2053 * If value==NULL, unset in (remove from) config,
2054 * if value_regex!=NULL, disregard key/value pairs where value does not match.