git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v8 0/8] Rewrite `git_config()` using config-set API

From
Tanay Abhra <tanayabh@gmail.com>
Date
Aug 8, 2014, 14:07 UTC
Message-ID
<53E4D986.6040708@gmail.com>
In-Reply-To
<xmqqoavwjb3i.fsf@gitster.dls.corp.google.com>
On 8/8/2014 2:01 AM, Junio C Hamano wrote:
Show 20 quoted lines
> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
> 
>>>> Why is this needed? Are you now using key_value_info outside config.c?
>>>> Or is it a leftover from a previous experiment?
>>>
>>> Has this been resolved in the new round?
>>
>> Tanay explained in another subthread why this was needed. For callers
>> iterating over the string_list who want to get the file/line info, they
>> need to be able to cast the void * pointer to struct key_value_info *.
> 
> For callers that want to see all the multi-values, it would be
> preferrable for the iterator to pass the filename and the linenumber
> to the callback function, instead of exposing its implementation
> detail as a single string list and telling them to pick it apart,
> no?
> 
> Not a very convincing argument, but OK for now in the sense that we
> can fix it later if we wanted to before it gets too late.
>
(cc to Ramsay)

The discussion in both threads (v8 and v9), boils down to this, is the `key_value_info` struct really required to be declared public or should be just an implementation detail. I will give you the context,

The usage of the above mentioned struct is only required for git_config_get_value_multi(). With the public struct, the code flow would look like,

-- 8< --
diff --git a/notes.c b/notes.c
index 5fe691d..b7ab115 100644
--- a/notes.c
+++ b/notes.c
@@ -961,19 +961,6 @@ void string_list_add_refs_from_colon_sep(struct string_list *list,
 	free(globs_copy);
 }

-static int notes_display_config(const char *k, const char *v, void *cb)
-{
-	int *load_refs = cb;
-
-	if (*load_refs && !strcmp(k, "notes.displayref")) {
-		if (!v)
-			config_error_nonbool(k);
-		string_list_add_refs_by_glob(&display_notes_refs, v);
-	}
-
-	return 0;
-}
-
 const char *default_notes_ref(void)
 {
 	const char *notes_ref = NULL;
@@ -1041,7 +1028,9 @@ struct notes_tree **load_notes_trees(struct string_list *refs)
 void init_display_notes(struct display_notes_opt *opt)
 {
 	char *display_ref_env;
-	int load_config_refs = 0;
+	const struct string_list *values;
+	struct key_value_info *kv_info;
+	int load_config_refs = 0, i;
 	display_notes_refs.strdup_strings = 1;

 	assert(!display_notes_trees);
@@ -1058,7 +1047,21 @@ void init_display_notes(struct display_notes_opt *opt)
 			load_config_refs = 1;
 	}

-	git_config(notes_display_config, &load_config_refs);
+	if (load_config_refs) {
+		values = git_config_get_value_multi("notes.displayref");
+		if (values) {
+			for (i = 0; i < values->nr; i++) {
+				if (!values->items[i].string) {
+					kv_info = values->items[i].util;
+					config_error_nonbool("notes.displayref");
+					git_die_config_linenr("notes.displayref", kv_info->filename, kv_info->linenr);
+				}
+				else
+					string_list_add_refs_by_glob(&display_notes_refs,
+								     values->items[i].string);
+			}
+		}
+	}

 	if (opt) {
 		struct string_list_item *item;
-- 8< --

We cannot use git_die_config() here because it is applicable to the last
value for a given variable.

Alternative solution to the problem can be a helper function like this,

git_die_config_index(key, value_index, err_msg, ...) which needs the value_index for a multi valued one,

+		values = git_config_get_value_multi("notes.displayref");
+		if (values) {
+			for (i = 0; i < values->nr; i++) {
+				if (!values->items[i].string)
+					git_die_config_linenr("notes.displayref", i, "no null values allowed for :'%s'", "notes.displayref");
+				else ; /* do stuff */
+			}

A callback iterator which supplies the linenr and filename to the callback
function is not helpful, because there are many variable checks in a
git_config() call where multi valued and single valued both reside, so we cannot
use a callback iterator without adding more code cruft.

What do you think, which way seems least obtrusive, or is there an another way out?
Previous: Junio C HamanoNext: Ramsay Jones
Message 19 of 22 in “Rewrite `git_config()` using config-set API”
  1. 0/8 Rewrite `git_config()` using config-set APITanay Abhra, Aug 6, 2014
  2. 1/8 config.c: mark error and warnings strings for translationTanay Abhra, Aug 6, 2014
  3. 2/8 config.c: fix accuracy of line number in errorsTanay Abhra, Aug 6, 2014
  4. 3/8 add line number and file name info to `config_set`Tanay Abhra, Aug 6, 2014
  5. Ramsay JonesAug 6, 2014
  6. 4/8 change `git_config()` return value to voidTanay Abhra, Aug 6, 2014
  7. 5/8 config: add `git_die_config()` to the config-set APITanay Abhra, Aug 6, 2014
  8. 6/8 rewrite git_config() to use the config-set APITanay Abhra, Aug 6, 2014
  9. 7/8 add a test for semantic errors in config filesTanay Abhra, Aug 6, 2014
  10. 8/8 add tests for `git_config_get_string_const()`Tanay Abhra, Aug 6, 2014
  11. Matthieu MoyAug 6, 2014
  12. Tanay AbhraAug 6, 2014
  13. Junio C HamanoAug 6, 2014
  14. Matthieu MoyAug 7, 2014
  15. Matthieu MoyAug 6, 2014
  16. Junio C HamanoAug 7, 2014
  17. Matthieu MoyAug 7, 2014
  18. Junio C HamanoAug 7, 2014
  19. Tanay AbhraAug 8, 2014
  20. Ramsay JonesAug 8, 2014
  21. Junio C HamanoAug 10, 2014
  22. Ramsay JonesAug 11, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.