All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Glen Choo via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: 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>, Glen Choo <chooglen@google.com>
Subject: [PATCH 3/6] config.c: create config_reader and the_reader
Date: Wed, 01 Mar 2023 00:38:14 +0000	[thread overview]
Message-ID: <751ce3e927d392530038006a3f1e3a9538ce2127.1677631097.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1463.git.git.1677631097.gitgitgadget@gmail.com>

From: Glen Choo <chooglen@google.com>

Create "struct config_reader" to hold the state of the config source
currently being read. Then, create a static instance of it,
"the_reader", and use "the_reader.source" to replace references to "cf"
in public functions.

This doesn't create much immediate benefit (since we're mostly replacing
static variables with a bigger static variable), but it prepares us for
a future where this state doesn't have to be global; the "struct
config_reader" could be provided by the caller, or constructed
internally by a function like "do_config_from()".

A more typical approach would be to put this struct on "the_repository",
but that's a worse fit for this use case since config reading is not
scoped to a repository. E.g. we can read config before the repository is
known ("read_very_early_config()"), blatantly ignore the repo
("read_protected_config()"), or read only from a file
("git_config_from_file()"). This is especially evident in t5318 and
t9210, where test-tool and scalar parse config but don't fully
initialize "the_repository".

We could have also replaced the references to "cf" in callback functions
(which are the only ones left), but we'll eventually plumb "the_reader"
through the callback "*data" arg, which will allow us to rename "cf" to
"cs" without changing line lengths. Until we remove "cf" altogether,
add logic to "config_reader_*_source()" to keep "cf" and
"the_reader.source" in sync.

Signed-off-by: Glen Choo <chooglen@google.com>
---
 config.c | 80 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 32 deletions(-)

diff --git a/config.c b/config.c
index 1f89addc771..866cd54dd40 100644
--- a/config.c
+++ b/config.c
@@ -51,6 +51,12 @@ struct config_source {
 };
 #define CONFIG_SOURCE_INIT { 0 }
 
+struct config_reader {
+	struct config_source *source;
+};
+/* Only public functions should reference the_reader. */
+static struct config_reader the_reader;
+
 /*
  * These variables record the "current" config source, which
  * can be accessed by parsing callbacks.
@@ -66,6 +72,9 @@ struct config_source {
  * 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).
+ *
+ * FIXME "cf" has been replaced by "the_reader.source", remove
+ * "cf" once we plumb "the_reader" through all of the callback functions.
  */
 static struct config_source *cf;
 static struct key_value_info *current_config_kvi;
@@ -79,20 +88,25 @@ static struct key_value_info *current_config_kvi;
  */
 static enum config_scope current_parsing_scope;
 
-static inline void config_state_push_source(struct config_source *top)
+static inline void config_reader_push_source(struct config_reader *reader,
+					     struct config_source *top)
 {
-	if (cf)
-		top->prev = cf;
-	cf = top;
+	if (reader->source)
+		top->prev = reader->source;
+	reader->source = top;
+	/* FIXME remove this when cf is removed. */
+	cf = reader->source;
 }
 
-static inline struct config_source *config_state_pop_source()
+static inline struct config_source *config_reader_pop_source(struct config_reader *reader)
 {
 	struct config_source *ret;
-	if (!cf)
+	if (!reader->source)
 		BUG("tried to pop config source, but we weren't reading config");
-	ret = cf;
-	cf = cf->prev;
+	ret = reader->source;
+	reader->source = reader->source->prev;
+	/* FIXME remove this when cf is removed. */
+	cf = reader->source;
 	return ret;
 }
 
@@ -732,7 +746,7 @@ int git_config_from_parameters(config_fn_t fn, void *data)
 	struct config_source source = CONFIG_SOURCE_INIT;
 
 	source.origin_type = CONFIG_ORIGIN_CMDLINE;
-	config_state_push_source(&source);
+	config_reader_push_source(&the_reader, &source);
 
 	env = getenv(CONFIG_COUNT_ENVIRONMENT);
 	if (env) {
@@ -790,7 +804,7 @@ out:
 	strbuf_release(&envvar);
 	strvec_clear(&to_free);
 	free(envw);
-	config_state_pop_source();
+	config_reader_pop_source(&the_reader);
 	return ret;
 }
 
@@ -1325,7 +1339,7 @@ int git_config_int(const char *name, const char *value)
 {
 	int ret;
 	if (!git_parse_int(value, &ret))
-		die_bad_number(cf, name, value);
+		die_bad_number(the_reader.source, name, value);
 	return ret;
 }
 
@@ -1333,7 +1347,7 @@ int64_t git_config_int64(const char *name, const char *value)
 {
 	int64_t ret;
 	if (!git_parse_int64(value, &ret))
-		die_bad_number(cf, name, value);
+		die_bad_number(the_reader.source, name, value);
 	return ret;
 }
 
@@ -1341,7 +1355,7 @@ unsigned long git_config_ulong(const char *name, const char *value)
 {
 	unsigned long ret;
 	if (!git_parse_ulong(value, &ret))
-		die_bad_number(cf, name, value);
+		die_bad_number(the_reader.source, name, value);
 	return ret;
 }
 
@@ -1349,7 +1363,7 @@ ssize_t git_config_ssize_t(const char *name, const char *value)
 {
 	ssize_t ret;
 	if (!git_parse_ssize_t(value, &ret))
-		die_bad_number(cf, name, value);
+		die_bad_number(the_reader.source, name, value);
 	return ret;
 }
 
@@ -1955,7 +1969,8 @@ int git_default_config(const char *var, const char *value, void *cb)
  * fgetc, ungetc, ftell of top need to be initialized before calling
  * this function.
  */
-static int do_config_from(struct config_source *top, config_fn_t fn, void *data,
+static int do_config_from(struct config_reader *reader,
+			  struct config_source *top, config_fn_t fn, void *data,
 			  const struct config_options *opts)
 {
 	int ret;
@@ -1966,22 +1981,23 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data,
 	top->total_len = 0;
 	strbuf_init(&top->value, 1024);
 	strbuf_init(&top->var, 1024);
-	config_state_push_source(top);
+	config_reader_push_source(reader, top);
 
 	ret = git_parse_source(top, fn, data, opts);
 
 	/* pop config-file parsing state stack */
 	strbuf_release(&top->value);
 	strbuf_release(&top->var);
-	config_state_pop_source();
+	config_reader_pop_source(reader);
 
 	return ret;
 }
 
-static int do_config_from_file(config_fn_t fn,
-		const enum config_origin_type origin_type,
-		const char *name, const char *path, FILE *f,
-		void *data, const struct config_options *opts)
+static int do_config_from_file(struct config_reader *reader,
+			       config_fn_t fn,
+			       const enum config_origin_type origin_type,
+			       const char *name, const char *path, FILE *f,
+			       void *data, const struct config_options *opts)
 {
 	struct config_source top = CONFIG_SOURCE_INIT;
 	int ret;
@@ -1996,15 +2012,15 @@ static int do_config_from_file(config_fn_t fn,
 	top.do_ftell = config_file_ftell;
 
 	flockfile(f);
-	ret = do_config_from(&top, fn, data, opts);
+	ret = do_config_from(reader, &top, fn, data, opts);
 	funlockfile(f);
 	return ret;
 }
 
 static int git_config_from_stdin(config_fn_t fn, void *data)
 {
-	return do_config_from_file(fn, CONFIG_ORIGIN_STDIN, "", NULL, stdin,
-				   data, NULL);
+	return do_config_from_file(&the_reader, fn, CONFIG_ORIGIN_STDIN, "",
+				   NULL, stdin, data, NULL);
 }
 
 int git_config_from_file_with_options(config_fn_t fn, const char *filename,
@@ -2018,8 +2034,8 @@ int git_config_from_file_with_options(config_fn_t fn, const char *filename,
 		BUG("filename cannot be NULL");
 	f = fopen_or_warn(filename, "r");
 	if (f) {
-		ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename,
-					  filename, f, data, opts);
+		ret = do_config_from_file(&the_reader, fn, CONFIG_ORIGIN_FILE,
+					  filename, filename, f, data, opts);
 		fclose(f);
 	}
 	return ret;
@@ -2048,7 +2064,7 @@ int git_config_from_mem(config_fn_t fn,
 	top.do_ungetc = config_buf_ungetc;
 	top.do_ftell = config_buf_ftell;
 
-	return do_config_from(&top, fn, data, opts);
+	return do_config_from(&the_reader, &top, fn, data, opts);
 }
 
 int git_config_from_blob_oid(config_fn_t fn,
@@ -3791,8 +3807,8 @@ const char *current_config_origin_type(void)
 	int type;
 	if (current_config_kvi)
 		type = current_config_kvi->origin_type;
-	else if(cf)
-		type = cf->origin_type;
+	else if(the_reader.source)
+		type = the_reader.source->origin_type;
 	else
 		BUG("current_config_origin_type called outside config callback");
 
@@ -3837,8 +3853,8 @@ const char *current_config_name(void)
 	const char *name;
 	if (current_config_kvi)
 		name = current_config_kvi->filename;
-	else if (cf)
-		name = cf->name;
+	else if (the_reader.source)
+		name = the_reader.source->name;
 	else
 		BUG("current_config_name called outside config callback");
 	return name ? name : "";
@@ -3857,7 +3873,7 @@ int current_config_line(void)
 	if (current_config_kvi)
 		return current_config_kvi->linenr;
 	else
-		return cf->linenr;
+		return the_reader.source->linenr;
 }
 
 int lookup_config(const char **mapping, int nr_mapping, const char *var)
-- 
gitgitgadget


  parent reply	other threads:[~2023-03-01  0:38 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 ` Glen Choo via GitGitGadget [this message]
2023-03-03 18:05   ` [PATCH 3/6] config.c: create config_reader and the_reader 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
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=751ce3e927d392530038006a3f1e3a9538ce2127.1677631097.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=chooglen@google.com \
    --cc=derrickstolee@github.com \
    --cc=git@vger.kernel.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.