mirror of
https://github.com/git/git
synced 2024-11-05 04:53:18 +00:00
a4e7e317f8
Add a new "const struct config_context *ctx" arg to config_fn_t to hold additional information about the config iteration operation. config_context has a "struct key_value_info kvi" member that holds metadata about the config source being read (e.g. what kind of config source it is, the filename, etc). In this series, we're only interested in .kvi, so we could have just used "struct key_value_info" as an arg, but config_context makes it possible to add/adjust members in the future without changing the config_fn_t signature. We could also consider other ways of organizing the args (e.g. moving the config name and value into config_context or key_value_info), but in my experiments, the incremental benefit doesn't justify the added complexity (e.g. a config_fn_t will sometimes invoke another config_fn_t but with a different config value). In subsequent commits, the .kvi member will replace the global "struct config_reader" in config.c, making config iteration a global-free operation. It requires much more work for the machinery to provide meaningful values of .kvi, so for now, merely change the signature and call sites, pass NULL as a placeholder value, and don't rely on the arg in any meaningful way. Most of the changes are performed by contrib/coccinelle/config_fn_ctx.pending.cocci, which, for every config_fn_t: - Modifies the signature to accept "const struct config_context *ctx" - Passes "ctx" to any inner config_fn_t, if needed - Adds UNUSED attributes to "ctx", if needed Most config_fn_t instances are easily identified by seeing if they are called by the various config functions. Most of the remaining ones are manually named in the .cocci patch. Manual cleanups are still needed, but the majority of it is trivial; it's either adjusting config_fn_t that the .cocci patch didn't catch, or adding forward declarations of "struct config_context ctx" to make the signatures make sense. The non-trivial changes are in cases where we are invoking a config_fn_t outside of config machinery, and we now need to decide what value of "ctx" to pass. These cases are: - trace2/tr2_cfg.c:tr2_cfg_set_fl() This is indirectly called by git_config_set() so that the trace2 machinery can notice the new config values and update its settings using the tr2 config parsing function, i.e. tr2_cfg_cb(). - builtin/checkout.c:checkout_main() This calls git_xmerge_config() as a shorthand for parsing a CLI arg. This might be worth refactoring away in the future, since git_xmerge_config() can call git_default_config(), which can do much more than just parsing. Handle them by creating a KVI_INIT macro that initializes "struct key_value_info" to a reasonable default, and use that to construct the "ctx" arg. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
78 lines
2.7 KiB
C
78 lines
2.7 KiB
C
#ifndef URL_MATCH_H
|
|
#define URL_MATCH_H
|
|
|
|
#include "string-list.h"
|
|
#include "config.h"
|
|
|
|
struct url_info {
|
|
/* normalized url on success, must be freed, otherwise NULL */
|
|
char *url;
|
|
/* if !url, a brief reason for the failure, otherwise NULL */
|
|
const char *err;
|
|
|
|
/* the rest of the fields are only set if url != NULL */
|
|
|
|
size_t url_len; /* total length of url (which is now normalized) */
|
|
size_t scheme_len; /* length of scheme name (excluding final :) */
|
|
size_t user_off; /* offset into url to start of user name (0 => none) */
|
|
size_t user_len; /* length of user name; if user_off != 0 but
|
|
user_len == 0, an empty user name was given */
|
|
size_t passwd_off; /* offset into url to start of passwd (0 => none) */
|
|
size_t passwd_len; /* length of passwd; if passwd_off != 0 but
|
|
passwd_len == 0, an empty passwd was given */
|
|
size_t host_off; /* offset into url to start of host name (0 => none) */
|
|
size_t host_len; /* length of host name;
|
|
* file urls may have host_len == 0 */
|
|
size_t port_off; /* offset into url to start of port number (0 => none) */
|
|
size_t port_len; /* if a portnum is present (port_off != 0), it has
|
|
* this length (excluding the leading ':') starting
|
|
* from port_off (always 0 for file urls) */
|
|
size_t path_off; /* offset into url to the start of the url path;
|
|
* this will always point to a '/' character
|
|
* after the url has been normalized */
|
|
size_t path_len; /* length of path portion excluding any trailing
|
|
* '?...' and '#...' portion; will always be >= 1 */
|
|
};
|
|
|
|
char *url_normalize(const char *, struct url_info *);
|
|
|
|
struct urlmatch_item {
|
|
size_t hostmatch_len;
|
|
size_t pathmatch_len;
|
|
char user_matched;
|
|
};
|
|
|
|
struct urlmatch_config {
|
|
struct string_list vars;
|
|
struct url_info url;
|
|
const char *section;
|
|
const char *key;
|
|
|
|
void *cb;
|
|
config_fn_t collect_fn;
|
|
config_fn_t cascade_fn;
|
|
/*
|
|
* Compare the two matches, the one just discovered and the existing
|
|
* best match and return a negative value if the found item is to be
|
|
* rejected or a non-negative value if it is to be accepted. If this
|
|
* field is set to NULL, use the default comparison technique, which
|
|
* checks to ses if found is better (according to the urlmatch
|
|
* specificity rules) than existing.
|
|
*/
|
|
int (*select_fn)(const struct urlmatch_item *found, const struct urlmatch_item *existing);
|
|
/*
|
|
* An optional callback to allow e.g. for partial URLs; it shall
|
|
* return 1 or 0 depending whether `url` matches or not.
|
|
*/
|
|
int (*fallback_match_fn)(const char *url, void *cb);
|
|
};
|
|
|
|
#define URLMATCH_CONFIG_INIT { \
|
|
.vars = STRING_LIST_INIT_DUP, \
|
|
}
|
|
|
|
int urlmatch_config_entry(const char *var, const char *value,
|
|
const struct config_context *ctx, void *cb);
|
|
void urlmatch_config_release(struct urlmatch_config *config);
|
|
|
|
#endif /* URL_MATCH_H */
|