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

[PATCH v8 04/12] trailer: read and process config information

From
Christian Couder <chriscool@tuxfamily.org>
Date
Mar 26, 2014, 22:15 UTC
Message-ID
<20140326221531.11352.31137.chriscool@tuxfamily.org>
In-Reply-To
<20140326215858.11352.89243.chriscool@tuxfamily.org>

Read the configuration to get trailer information, and then process it and storing it in a doubly linked list.

The config information is stored in the list whose first item is pointed to by:

static struct trailer_item *first_conf_item;
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 trailer.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)
diff --git a/trailer.c b/trailer.c
index 52108c2..b5a0943 100644
--- a/trailer.c
+++ b/trailer.c
@@ -25,6 +25,8 @@ struct trailer_item {
 	struct conf_info conf;
 };
 
+static struct trailer_item *first_conf_item;
+
 static int same_token(struct trailer_item *a, struct trailer_item *b, int alnum_len)
 {
 	return !strncasecmp(a->token, b->token, alnum_len);
@@ -245,3 +247,154 @@ static void process_trailers_lists(struct trailer_item **in_tok_first,
 		apply_arg_if_missing(in_tok_first, in_tok_last, arg_tok);
 	}
 }
+
+static int set_where(struct conf_info *item, const char *value)
+{
+	if (!strcmp("after", value))
+		item->where = WHERE_AFTER;
+	else if (!strcmp("before", value))
+		item->where = WHERE_BEFORE;
+	else
+		return -1;
+	return 0;
+}
+
+static int set_if_exists(struct conf_info *item, const char *value)
+{
+	if (!strcmp("addifdifferent", value))
+		item->if_exists = EXISTS_ADD_IF_DIFFERENT;
+	else if (!strcmp("addifdifferentneighbor", value))
+		item->if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
+	else if (!strcmp("add", value))
+		item->if_exists = EXISTS_ADD;
+	else if (!strcmp("overwrite", value))
+		item->if_exists = EXISTS_OVERWRITE;
+	else if (!strcmp("donothing", value))
+		item->if_exists = EXISTS_DO_NOTHING;
+	else
+		return -1;
+	return 0;
+}
+
+static int set_if_missing(struct conf_info *item, const char *value)
+{
+	if (!strcmp("donothing", value))
+		item->if_missing = MISSING_DO_NOTHING;
+	else if (!strcmp("add", value))
+		item->if_missing = MISSING_ADD;
+	else
+		return -1;
+	return 0;
+}
+
+static struct trailer_item *get_conf_item(const char *name)
+{
+	struct trailer_item *item;
+	struct trailer_item *previous;
+
+	/* Look up item with same name */
+	for (previous = NULL, item = first_conf_item;
+	     item;
+	     previous = item, item = item->next) {
+		if (!strcasecmp(item->conf.name, name))
+			return item;
+	}
+
+	/* Item does not already exists, create it */
+	item = xcalloc(sizeof(struct trailer_item), 1);
+	item->conf.name = xstrdup(name);
+
+	if (!previous)
+		first_conf_item = item;
+	else {
+		previous->next = item;
+		item->previous = previous;
+	}
+
+	return item;
+}
+
+enum trailer_info_type { TRAILER_KEY, TRAILER_COMMAND, TRAILER_WHERE,
+			 TRAILER_IF_EXISTS, TRAILER_IF_MISSING };
+
+static struct {
+	const char *name;
+	enum trailer_info_type type;
+} trailer_config_items[] = {
+	{ "key", TRAILER_KEY },
+	{ "command", TRAILER_COMMAND },
+	{ "where", TRAILER_WHERE },
+	{ "ifexists", TRAILER_IF_EXISTS },
+	{ "ifmissing", TRAILER_IF_MISSING }
+};
+
+static int git_trailer_config(const char *conf_key, const char *value, void *cb)
+{
+	const char *trailer_item, *variable_name;
+	struct trailer_item *item;
+	struct conf_info *conf;
+	char *name = NULL;
+	enum trailer_info_type type;
+	char *lowercase_value;
+	int i;
+
+	trailer_item = skip_prefix(conf_key, "trailer.");
+	if (!trailer_item)
+		return 0;
+
+	variable_name = strrchr(trailer_item, '.');
+	if (!variable_name) {
+		warning(_("two level trailer config variable %s"), conf_key);
+		return 0;
+	}
+
+	variable_name++;
+	for (i = 0; i < ARRAY_SIZE(trailer_config_items); i++) {
+		if (strcmp(trailer_config_items[i].name, variable_name))
+			continue;
+		name = xstrndup(trailer_item,  variable_name - trailer_item -1);
+		type = trailer_config_items[i].type;
+		break;
+	}
+
+	if (!name)
+		return 0;
+
+	item = get_conf_item(name);
+	conf = &item->conf;
+	free(name);
+
+	switch (type) {
+	case TRAILER_KEY:
+		if (conf->key)
+			warning(_("more than one %s"), conf_key);
+		conf->key = xstrdup(value);
+		break;
+	case TRAILER_COMMAND:
+		if (conf->command)
+			warning(_("more than one %s"), conf_key);
+		conf->command = xstrdup(value);
+		break;
+	case TRAILER_WHERE:
+		lowercase_value = xstrdup_tolower(value);
+		if (set_where(conf, lowercase_value))
+			warning(_("unknown value '%s' for key '%s'"), value, conf_key);
+		free(lowercase_value);
+		break;
+	case TRAILER_IF_EXISTS:
+		lowercase_value = xstrdup_tolower(value);
+		if (set_if_exists(conf, lowercase_value))
+			warning(_("unknown value '%s' for key '%s'"), value, conf_key);
+		free(lowercase_value);
+		break;
+	case TRAILER_IF_MISSING:
+		lowercase_value = xstrdup_tolower(value);
+		if (set_if_missing(conf, lowercase_value))
+			warning(_("unknown value '%s' for key '%s'"), value, conf_key);
+		free(lowercase_value);
+		break;
+	default:
+		die("internal bug in trailer.c");
+	}
+	return 0;
+}
-- 
1.9.0.164.g3aa33cd.dirty
Previous: Christian CouderNext: Christian Couder
Message 17 of 27 in “Add interpret-trailers builtin”
  1. 00/12 Add interpret-trailers builtinChristian Couder, Mar 26, 2014
  2. 01/12 Add data structures and basic functions for commit trailersChristian Couder, Mar 26, 2014
  3. Junio C HamanoMar 26, 2014
  4. Christian CouderMar 27, 2014
  5. 02/12 trailer: process trailers from stdin and argumentsChristian Couder, Mar 26, 2014
  6. 03/12 Move lower case functions into wrapper.cChristian Couder, Mar 26, 2014
  7. Junio C HamanoMar 26, 2014
  8. Christian CouderMar 27, 2014
  9. Junio C HamanoMar 27, 2014
  10. Junio C HamanoMar 27, 2014
  11. Jeff KingMar 27, 2014
  12. Junio C HamanoMar 27, 2014
  13. Jeff KingMar 27, 2014
  14. Junio C HamanoMar 28, 2014
  15. Jeff KingMar 28, 2014
  16. Christian CouderMar 28, 2014
  17. 04/12 trailer: read and process config informationChristian Couder, Mar 26, 2014
  18. 05/12 trailer: process command line trailer argumentsChristian Couder, Mar 26, 2014
  19. 06/12 trailer: parse trailers from stdinChristian Couder, Mar 26, 2014
  20. 07/12 trailer: put all the processing together and printChristian Couder, Mar 26, 2014
  21. 08/12 trailer: add interpret-trailers commandChristian Couder, Mar 26, 2014
  22. 09/12 trailer: add tests for "git interpret-trailers"Christian Couder, Mar 26, 2014
  23. 10/12 trailer: execute command from 'trailer.<name>.command'Christian Couder, Mar 26, 2014
  24. 11/12 trailer: add tests for commands in config fileChristian Couder, Mar 26, 2014
  25. 12/12 Documentation: add documentation for 'git interpret-trailers'Christian Couder, Mar 26, 2014
  26. Junio C HamanoMar 26, 2014
  27. Christian CouderMar 27, 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.