git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Calvin Wan <calvinwan@google.com>
To: Glen Choo via GitGitGadget <gitgitgadget@gmail.com>
Cc: Calvin Wan <calvinwan@google.com>,
	git@vger.kernel.org, Jonathan Tan <jonathantanmy@google.com>,
	Emily Shaffer <nasamuffin@google.com>, Jeff King <peff@peff.net>,
	Derrick Stolee <derrickstolee@github.com>,
	Glen Choo <chooglen@google.com>
Subject: Re: [PATCH 5/6] config.c: remove current_config_kvi
Date: Mon,  6 Mar 2023 20:12:18 +0000	[thread overview]
Message-ID: <20230306201218.2834756-1-calvinwan@google.com> (raw)
In-Reply-To: <c05b33ab29dbce931f9d0ad968fe9eeedc653456.1677631097.git.gitgitgadget@gmail.com>

"Glen Choo via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Glen Choo <chooglen@google.com>
> 
> Add ".config_kvi" to "struct config_reader" and replace
> "current_config_kvi" with "the_reader.config_kvi", either in-place (in
> public functions) or by passing "the_reader" to the "*data" arg of
> callback functions.
> 
> Also, introduce a setter function for ".config_kvi", which allows us to
> enforce the contraint that only one of ".source" and ".config_kvi" can
> be set at a time (as documented in the comments). Because of this
> constraint, we know that "populate_remote_urls()" was never touching
> "current_config_kvi" when iterating through config files, so it doesn't
> need to store and restore that value.
> 
> Signed-off-by: Glen Choo <chooglen@google.com>
> ---
>  config.c | 103 ++++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 61 insertions(+), 42 deletions(-)
> 
> diff --git a/config.c b/config.c
> index 9676734b1b7..c7995148165 100644
> --- a/config.c
> +++ b/config.c
> @@ -52,32 +52,28 @@ struct config_source {
>  #define CONFIG_SOURCE_INIT { 0 }
>  
>  struct config_reader {
> +	/*
> +	 * These members record the "current" config source, which can be
> +	 * accessed by parsing callbacks.
> +	 *
> +	 * The "source" variable will be non-NULL only when we are actually
> +	 * parsing a real config source (file, blob, cmdline, etc).
> +	 *
> +	 * The "config_kvi" variable will be non-NULL only when we are feeding
> +	 * cached config from a configset into a callback.
> +	 *
> +	 * They cannot be non-NULL at the same time. If they are both NULL, then
> +	 * we aren't parsing anything (and depending on the function looking at
> +	 * the variables, it's either a bug for it to be called in the first
> +	 * place, or it's a function which can be reused for non-config
> +	 * purposes, and should fall back to some sane behavior).
> +	 */
>  	struct config_source *source;
> +	struct key_value_info *config_kvi;
>  };
>  /* Only public functions should reference the_reader. */
>  static struct config_reader the_reader;
>  
> -/*
> - * FIXME The comments are temporarily out of date since "cf" been moved to
> - * the_reader, but not current_*.
> - *
> - * These variables record the "current" config source, which
> - * can be accessed by parsing callbacks.
> - *
> - * The "cf" variable will be non-NULL only when we are actually parsing a real
> - * config source (file, blob, cmdline, etc).
> - *
> - * The "current_config_kvi" variable will be non-NULL only when we are feeding
> - * cached config from a configset into a callback.
> - *
> - * They should generally never be non-NULL at the same time. If they are both
> - * NULL, then we aren't parsing anything (and depending on the function looking
> - * at the variables, it's either a bug for it to be called in the first place,
> - * or it's a function which can be reused for non-config purposes, and should
> - * fall back to some sane behavior).
> - */
> -static struct key_value_info *current_config_kvi;
> -
>  /*
>   * Similar to the variables above, this gives access to the "scope" of the
>   * current value (repo, global, etc). For cached values, it can be found via
> @@ -90,6 +86,8 @@ static enum config_scope current_parsing_scope;
>  static inline void config_reader_push_source(struct config_reader *reader,
>  					     struct config_source *top)
>  {
> +	if (reader->config_kvi)
> +		BUG("source should only be set when parsing a config source");
>  	if (reader->source)
>  		top->prev = reader->source;
>  	reader->source = top;

A developer who accidentally sets config_kvi probably has the right
intention of trying to push source. I think a clearer BUG message here
(which also doubly functions as a useful comment) would be something
along the lines of: "configset should not be set when parsing a config
source".

> @@ -105,6 +103,14 @@ static inline struct config_source *config_reader_pop_source(struct config_reade
>  	return ret;
>  }
>  
> +static inline void config_reader_set_kvi(struct config_reader *reader,
> +					 struct key_value_info *kvi)
> +{
> +	if (kvi && reader->source)
> +		BUG("kvi should only be set when iterating through configset");
> +	reader->config_kvi = kvi;
> +}
> +

ditto

>  static int pack_compression_seen;
>  static int zlib_compression_seen;
>  
> @@ -373,20 +379,17 @@ static void populate_remote_urls(struct config_include_data *inc)
>  {
>  	struct config_options opts;
>  
> -	struct key_value_info *store_kvi = current_config_kvi;
>  	enum config_scope store_scope = current_parsing_scope;
>  
>  	opts = *inc->opts;
>  	opts.unconditional_remote_url = 1;
>  
> -	current_config_kvi = NULL;
>  	current_parsing_scope = 0;
>  
>  	inc->remote_urls = xmalloc(sizeof(*inc->remote_urls));
>  	string_list_init_dup(inc->remote_urls);
>  	config_with_options(add_remote_url, inc->remote_urls, inc->config_source, &opts);
>  
> -	current_config_kvi = store_kvi;
>  	current_parsing_scope = store_scope;
>  }
>  
> @@ -2253,26 +2256,34 @@ int config_with_options(config_fn_t fn, void *data,
>  	return ret;
>  }
>  
> +struct configset_iter_data {
> +	struct config_reader *config_reader;
> +	void *inner;
> +};
> +#define CONFIGSET_ITER_INIT { 0 }
> +
>  static void configset_iter(struct config_set *cs, config_fn_t fn, void *data)
>  {
>  	int i, value_index;
>  	struct string_list *values;
>  	struct config_set_element *entry;
>  	struct configset_list *list = &cs->list;
> +	struct configset_iter_data *iter_data = data;
>  
>  	for (i = 0; i < list->nr; i++) {
> +		struct key_value_info *kvi;
>  		entry = list->items[i].e;
>  		value_index = list->items[i].value_index;
>  		values = &entry->value_list;
>  
> -		current_config_kvi = values->items[value_index].util;
> +		kvi = values->items[value_index].util;
> +		config_reader_set_kvi(iter_data->config_reader, kvi);
>  
> -		if (fn(entry->key, values->items[value_index].string, data) < 0)
> -			git_die_config_linenr(entry->key,
> -					      current_config_kvi->filename,
> -					      current_config_kvi->linenr);
> +		if (fn(entry->key, values->items[value_index].string, iter_data->inner) < 0)
> +			git_die_config_linenr(entry->key, kvi->filename,
> +					      kvi->linenr);
>  
> -		current_config_kvi = NULL;
> +		config_reader_set_kvi(iter_data->config_reader, NULL);
>  	}
>  }
>  
> @@ -2607,10 +2618,14 @@ static void repo_config_clear(struct repository *repo)
>  	git_configset_clear(repo->config);
>  }
>  
> -void repo_config(struct repository *repo, config_fn_t fn, void *data)
> +void repo_config(struct repository *repo, config_fn_t fn, void *data_inner)
>  {
> +	struct configset_iter_data data = CONFIGSET_ITER_INIT;
> +	data.inner = data_inner;
> +	data.config_reader = &the_reader;
> +
>  	git_config_check_init(repo);
> -	configset_iter(repo->config, fn, data);
> +	configset_iter(repo->config, fn, &data);
>  }

I'm not sure I agree with changing *data to *data_inner. An API caller
would be wondering why this function has a *data_inner signature vs
*data for other functions in config. You could instead change `struct
configset_iter_data data` to `struct configset_iter_data data_outer` to
preserve the function signature.

>  
>  int repo_config_get_value(struct repository *repo,
> @@ -2712,11 +2727,15 @@ static void read_protected_config(void)
>  	config_with_options(config_set_callback, &data, NULL, &opts);
>  }
>  
> -void git_protected_config(config_fn_t fn, void *data)
> +void git_protected_config(config_fn_t fn, void *data_inner)
>  {
> +	struct configset_iter_data data = CONFIGSET_ITER_INIT;
>  	if (!protected_config.hash_initialized)
>  		read_protected_config();
> -	configset_iter(&protected_config, fn, data);
> +	data.inner = data_inner;
> +	data.config_reader = &the_reader;
> +
> +	configset_iter(&protected_config, fn, &data);
>  }

ditto

>  
>  /* Functions used historically to read configuration from 'the_repository' */
> @@ -3823,8 +3842,8 @@ int parse_config_key(const char *var,
>  const char *current_config_origin_type(void)
>  {
>  	int type;
> -	if (current_config_kvi)
> -		type = current_config_kvi->origin_type;
> +	if (the_reader.config_kvi)
> +		type = the_reader.config_kvi->origin_type;
>  	else if(the_reader.source)
>  		type = the_reader.source->origin_type;
>  	else
> @@ -3869,8 +3888,8 @@ const char *config_scope_name(enum config_scope scope)
>  const char *current_config_name(void)
>  {
>  	const char *name;
> -	if (current_config_kvi)
> -		name = current_config_kvi->filename;
> +	if (the_reader.config_kvi)
> +		name = the_reader.config_kvi->filename;
>  	else if (the_reader.source)
>  		name = the_reader.source->name;
>  	else
> @@ -3880,16 +3899,16 @@ const char *current_config_name(void)
>  
>  enum config_scope current_config_scope(void)
>  {
> -	if (current_config_kvi)
> -		return current_config_kvi->scope;
> +	if (the_reader.config_kvi)
> +		return the_reader.config_kvi->scope;
>  	else
>  		return current_parsing_scope;
>  }
>  
>  int current_config_line(void)
>  {
> -	if (current_config_kvi)
> -		return current_config_kvi->linenr;
> +	if (the_reader.config_kvi)
> +		return the_reader.config_kvi->linenr;
>  	else
>  		return the_reader.source->linenr;
>  }
> -- 
> gitgitgadget
> 
> 
> 

  reply	other threads:[~2023-03-06 20:13 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-01  0:38 [PATCH 0/6] [RFC] config.c: use struct for config reading state Glen Choo via GitGitGadget
2023-03-01  0:38 ` [PATCH 1/6] config.c: plumb config_source through static fns Glen Choo via GitGitGadget
2023-03-03 18:02   ` Junio C Hamano
2023-03-01  0:38 ` [PATCH 2/6] config.c: don't assign to "cf" directly Glen Choo via GitGitGadget
2023-03-01  0:38 ` [PATCH 3/6] config.c: create config_reader and the_reader Glen Choo via GitGitGadget
2023-03-03 18:05   ` Junio C Hamano
2023-03-01  0:38 ` [PATCH 4/6] config.c: plumb the_reader through callbacks Glen Choo via GitGitGadget
2023-03-08  9:54   ` Ævar Arnfjörð Bjarmason
2023-03-08 18:00     ` Glen Choo
2023-03-08 18:07       ` Junio C Hamano
2023-03-01  0:38 ` [PATCH 5/6] config.c: remove current_config_kvi Glen Choo via GitGitGadget
2023-03-06 20:12   ` Calvin Wan [this message]
2023-03-01  0:38 ` [PATCH 6/6] config.c: remove current_parsing_scope Glen Choo via GitGitGadget
2023-03-06 19:57 ` [PATCH 0/6] [RFC] config.c: use struct for config reading state Jonathan Tan
2023-03-06 21:45   ` Glen Choo
2023-03-06 22:38     ` Jonathan Tan
2023-03-08 10:32       ` Ævar Arnfjörð Bjarmason
2023-03-08 23:09         ` Glen Choo
2023-03-07 11:57 ` Ævar Arnfjörð Bjarmason
2023-03-07 18:22   ` Glen Choo
2023-03-07 18:36     ` Ævar Arnfjörð Bjarmason
2023-03-07 19:36     ` Junio C Hamano
2023-03-07 22:53       ` Glen Choo
2023-03-08  9:17         ` Ævar Arnfjörð Bjarmason
2023-03-08 23:18           ` Glen Choo
2023-03-16  0:11 ` [PATCH v2 0/8] " Glen Choo via GitGitGadget
2023-03-16  0:11   ` [PATCH v2 1/8] config.c: plumb config_source through static fns Glen Choo via GitGitGadget
2023-03-16 21:16     ` Jonathan Tan
2023-03-16  0:11   ` [PATCH v2 2/8] config.c: don't assign to "cf_global" directly Glen Choo via GitGitGadget
2023-03-16 21:18     ` Jonathan Tan
2023-03-16 21:31       ` Junio C Hamano
2023-03-16 22:56       ` Glen Choo
2023-03-16  0:11   ` [PATCH v2 3/8] config.c: create config_reader and the_reader Glen Choo via GitGitGadget
2023-03-16 21:22     ` Jonathan Tan
2023-03-16  0:11   ` [PATCH v2 4/8] config.c: plumb the_reader through callbacks Glen Choo via GitGitGadget
2023-03-16  0:11   ` [PATCH v2 5/8] config.c: remove current_config_kvi Glen Choo via GitGitGadget
2023-03-16  0:11   ` [PATCH v2 6/8] config.c: remove current_parsing_scope Glen Choo via GitGitGadget
2023-03-16  0:11   ` [PATCH v2 7/8] config: report cached filenames in die_bad_number() Glen Choo via GitGitGadget
2023-03-16 22:22     ` Jonathan Tan
2023-03-16 23:05       ` Glen Choo
2023-03-16  0:11   ` [PATCH v2 8/8] config.c: rename "struct config_source cf" Glen Choo via GitGitGadget
2023-03-16  0:15   ` [PATCH v2 0/8] config.c: use struct for config reading state Glen Choo
2023-03-16 22:29   ` Jonathan Tan
2023-03-17  5:01   ` [RFC PATCH 0/5] bypass config.c global state with configset Ævar Arnfjörð Bjarmason
2023-03-17  5:01     ` [RFC PATCH 1/5] config.h: move up "struct key_value_info" Ævar Arnfjörð Bjarmason
2023-03-17  5:01     ` [RFC PATCH 2/5] config.c: use "enum config_origin_type", not "int" Ævar Arnfjörð Bjarmason
2023-03-17  5:01     ` [RFC PATCH 3/5] config API: add a config_origin_type_name() helper Ævar Arnfjörð Bjarmason
2023-03-17  5:01     ` [RFC PATCH 4/5] config.c: refactor configset_iter() Ævar Arnfjörð Bjarmason
2023-03-17  5:01     ` [RFC PATCH 5/5] config API: add and use a repo_config_kvi() Ævar Arnfjörð Bjarmason
2023-03-17 17:17       ` Junio C Hamano
2023-03-17 20:59       ` Jonathan Tan
2023-03-17 16:21     ` [RFC PATCH 0/5] bypass config.c global state with configset Junio C Hamano
2023-03-17 16:28     ` Glen Choo
2023-03-17 19:20     ` Glen Choo
2023-03-17 23:32       ` Glen Choo
2023-03-29 11:53       ` Ævar Arnfjörð Bjarmason
2023-03-28 17:51   ` [PATCH v3 0/8] config.c: use struct for config reading state Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 1/8] config.c: plumb config_source through static fns Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 2/8] config.c: don't assign to "cf_global" directly Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 3/8] config.c: create config_reader and the_reader Glen Choo via GitGitGadget
2023-03-29 10:41       ` Ævar Arnfjörð Bjarmason
2023-03-29 18:57         ` Junio C Hamano
2023-03-29 20:02           ` Glen Choo
2023-03-30 17:51         ` Glen Choo
2023-03-28 17:51     ` [PATCH v3 4/8] config.c: plumb the_reader through callbacks Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 5/8] config.c: remove current_config_kvi Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 6/8] config.c: remove current_parsing_scope Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 7/8] config: report cached filenames in die_bad_number() Glen Choo via GitGitGadget
2023-03-28 17:51     ` [PATCH v3 8/8] config.c: rename "struct config_source cf" Glen Choo via GitGitGadget
2023-03-28 18:00     ` [PATCH v3 0/8] config.c: use struct for config reading state Glen Choo
2023-03-28 20:14       ` Junio C Hamano
2023-03-28 21:24         ` Glen Choo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230306201218.2834756-1-calvinwan@google.com \
    --to=calvinwan@google.com \
    --cc=chooglen@google.com \
    --cc=derrickstolee@github.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=jonathantanmy@google.com \
    --cc=nasamuffin@google.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).