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

[PATCH v3 23/27] attr: remove maybe-real, maybe-macro from git_attr

From
BWBrandon Williams <bmwill@google.com>
Date
Jan 28, 2017, 02:02 UTC
Message-ID
<20170128020207.179015-24-bmwill@google.com>
In-Reply-To
<20170128020207.179015-1-bmwill@google.com>

Whether or not a git attribute is real or a macro isn't a property of the attribute but rather it depends on the attribute stack (which .gitattribute files were read).

This patch removes the 'maybe_real' and 'maybe_macro' fields in a git_attr and instead adds the 'macro' field to a attr_check_item. The 'macro' indicates (if non-NULL) that a particular attribute is a macro for the given attribute stack. It's populated, through a quick scan of the attribute stack, with the match_attr that corresponds to the macro's definition. This way the attribute stack only needs to be scanned a single time prior to attribute collection instead of each time a macro needs to be expanded.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 attr.c | 75 +++++++++++++++++++++++++++++++++---------------------------------
 1 file changed, 37 insertions(+), 38 deletions(-)
diff --git a/attr.c b/attr.c
index 2637804b1..8f4402ef3 100644
--- a/attr.c
+++ b/attr.c
@@ -30,20 +30,9 @@ static const char git_attr__unknown[] = "(builtin)unknown";
 
 struct git_attr {
 	int attr_nr; /* unique attribute number */
-	int maybe_macro;
-	int maybe_real;
 	char name[FLEX_ARRAY]; /* attribute name */
 };
 
-/*
- * NEEDSWORK: maybe-real, maybe-macro are not property of
- * an attribute, as it depends on what .gitattributes are
- * read.  Once we introduce per git_attr_check attr_stack
- * and check_all_attr, the optimization based on them will
- * become unnecessary and can go away.  So is this variable.
- */
-static int cannot_trust_maybe_real;
-
 const char *git_attr_name(const struct git_attr *attr)
 {
 	return attr->name;
@@ -142,6 +131,12 @@ static void attr_hashmap_add(struct attr_hashmap *map,
 struct all_attrs_item {
 	const struct git_attr *attr;
 	const char *value;
+	/*
+	 * If 'macro' is non-NULL, indicates that 'attr' is a macro based on
+	 * the current attribute stack and contains a pointer to the match_attr
+	 * definition of the macro
+	 */
+	const struct match_attr *macro;
 };
 
 /*
@@ -187,6 +182,7 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check)
 	 */
 	for (i = 0; i < check->all_attrs_nr; i++) {
 		check->all_attrs[i].value = ATTR__UNKNOWN;
+		check->all_attrs[i].macro = NULL;
 	}
 }
 
@@ -238,8 +234,6 @@ static struct git_attr *git_attr_internal(const char *name, int namelen)
 	if (!a) {
 		FLEX_ALLOC_MEM(a, name, name, namelen);
 		a->attr_nr = g_attr_hashmap.map.size;
-		a->maybe_real = 0;
-		a->maybe_macro = 0;
 
 		attr_hashmap_add(&g_attr_hashmap, a->name, namelen, a);
 		assert(a->attr_nr == (g_attr_hashmap.map.size - 1));
@@ -402,7 +396,6 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
 		      (is_macro ? 0 : namelen + 1));
 	if (is_macro) {
 		res->u.attr = git_attr_internal(name, namelen);
-		res->u.attr->maybe_macro = 1;
 	} else {
 		char *p = (char *)&(res->state[num_attr]);
 		memcpy(p, name, namelen);
@@ -423,10 +416,6 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
 	/* Second pass to fill the attr_states */
 	for (cp = states, i = 0; *cp; i++) {
 		cp = parse_attr(src, lineno, cp, &(res->state[i]));
-		if (!is_macro)
-			res->state[i].attr->maybe_real = 1;
-		if (res->state[i].attr->maybe_macro)
-			cannot_trust_maybe_real = 1;
 	}
 
 	strbuf_release(&pattern);
@@ -904,7 +893,7 @@ static int path_matches(const char *pathname, int pathlen,
 static int macroexpand_one(struct all_attrs_item *all_attrs, int nr, int rem);
 
 static int fill_one(const char *what, struct all_attrs_item *all_attrs,
-		    struct match_attr *a, int rem)
+		    const struct match_attr *a, int rem)
 {
 	int i;
 
@@ -945,24 +934,34 @@ static int fill(const char *path, int pathlen, int basename_offset,
 
 static int macroexpand_one(struct all_attrs_item *all_attrs, int nr, int rem)
 {
-	struct attr_stack *stk;
-	int i;
+	const struct all_attrs_item *item = &all_attrs[nr];
 
-	if (all_attrs[nr].value != ATTR__TRUE ||
-	    !all_attrs[nr].attr->maybe_macro)
+	if (item->macro && item->value == ATTR__TRUE)
+		return fill_one("expand", all_attrs, item->macro, rem);
+	else
 		return rem;
+}
 
-	for (stk = attr_stack; stk; stk = stk->prev) {
-		for (i = stk->num_matches - 1; 0 <= i; i--) {
-			struct match_attr *ma = stk->attrs[i];
-			if (!ma->is_macro)
-				continue;
-			if (ma->u.attr->attr_nr == nr)
-				return fill_one("expand", all_attrs, ma, rem);
+/*
+ * Marks the attributes which are macros based on the attribute stack.
+ * This prevents having to search through the attribute stack each time
+ * a macro needs to be expanded during the fill stage.
+ */
+static void determine_macros(struct all_attrs_item *all_attrs,
+			     const struct attr_stack *stack)
+{
+	for (; stack; stack = stack->prev) {
+		int i;
+		for (i = stack->num_matches - 1; i >= 0; i--) {
+			const struct match_attr *ma = stack->attrs[i];
+			if (ma->is_macro) {
+				int n = ma->u.attr->attr_nr;
+				if (!all_attrs[n].macro) {
+					all_attrs[n].macro = ma;
+				}
+			}
 		}
 	}
-
-	return rem;
 }
 
 /*
@@ -992,15 +991,15 @@ static void collect_some_attrs(const char *path, struct attr_check *check)
 
 	prepare_attr_stack(path, dirlen);
 	all_attrs_init(&g_attr_hashmap, check);
+	determine_macros(check->all_attrs, attr_stack);
 
-	if (check->nr && !cannot_trust_maybe_real) {
+	if (check->nr) {
 		rem = 0;
 		for (i = 0; i < check->nr; i++) {
-			const struct git_attr *a = check->items[i].attr;
-			if (!a->maybe_real) {
-				struct all_attrs_item *c;
-				c = check->all_attrs + a->attr_nr;
-				c->value = ATTR__UNSET;
+			int n = check->items[i].attr->attr_nr;
+			struct all_attrs_item *item = &check->all_attrs[n];
+			if (item->macro) {
+				item->value = ATTR__UNSET;
 				rem++;
 			}
 		}
-- 
2.11.0.483.g087da7b7c-goog
Previous: Brandon WilliamsNext: Junio C Hamano
Message 108 of 111 in “Revamp the attribute system; another round”
  1. 00/27 Revamp the attribute system; another roundBrandon Williams, Jan 12, 2017
  2. 20/27 attr: change validity check for attribute names to use positive logicBrandon Williams, Jan 12, 2017
  3. 19/27 attr: pass struct attr_check to collect_some_attrsBrandon Williams, Jan 12, 2017
  4. 18/27 attr: retire git_check_attrs() APIBrandon Williams, Jan 12, 2017
  5. 17/27 attr: convert git_check_attrs() callers to use the new APIBrandon Williams, Jan 12, 2017
  6. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 12, 2017
  7. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 12, 2017
  8. 23/27 attr: remove maybe-real, maybe-macro from git_attrBrandon Williams, Jan 12, 2017
  9. 24/27 attr: tighten const correctness with git_attr and match_attrBrandon Williams, Jan 12, 2017
  10. 21/27 attr: use hashmap for attribute dictionaryBrandon Williams, Jan 12, 2017
  11. Stefan BellerJan 18, 2017
  12. Brandon WilliamsJan 18, 2017
  13. 25/27 attr: store attribute stacks in hashmapBrandon Williams, Jan 12, 2017
  14. Junio C HamanoJan 13, 2017
  15. Brandon WilliamsJan 18, 2017
  16. Brandon WilliamsJan 23, 2017
  17. Stefan BellerJan 18, 2017
  18. Brandon WilliamsJan 18, 2017
  19. Stefan BellerJan 18, 2017
  20. 22/27 attr: eliminate global check_all_attr arrayBrandon Williams, Jan 12, 2017
  21. 27/27 attr: reformat git_attr_set_direction() functionBrandon Williams, Jan 12, 2017
  22. 26/27 attr: push the bare repo check into read_attr()Brandon Williams, Jan 12, 2017
  23. 13/27 attr.c: outline the future plans by heavily commentingBrandon Williams, Jan 12, 2017
  24. 12/27 Documentation: fix a typoBrandon Williams, Jan 12, 2017
  25. 01/27 commit.c: use strchrnul() to scan for one lineBrandon Williams, Jan 12, 2017
  26. 02/27 attr.c: use strchrnul() to scan for one lineBrandon Williams, Jan 12, 2017
  27. 11/27 attr.c: add push_stack() helperBrandon Williams, Jan 12, 2017
  28. 08/27 attr.c: tighten constness around "git_attr" structureBrandon Williams, Jan 12, 2017
  29. 14/27 attr: rename function and struct related to checking attributesBrandon Williams, Jan 12, 2017
  30. 06/27 attr.c: mark where #if DEBUG ends more clearlyBrandon Williams, Jan 12, 2017
  31. 07/27 attr.c: simplify macroexpand_one()Brandon Williams, Jan 12, 2017
  32. 10/27 attr: support quoting pathname patterns in C styleBrandon Williams, Jan 12, 2017
  33. 09/27 attr.c: plug small leak in parse_attr_line()Brandon Williams, Jan 12, 2017
  34. 04/27 attr.c: explain the lack of attr-name syntax check in parse_attr()Brandon Williams, Jan 12, 2017
  35. 05/27 attr.c: complete a sentence in a commentBrandon Williams, Jan 12, 2017
  36. 03/27 attr.c: update a stale comment on "struct match_attr"Brandon Williams, Jan 12, 2017
  37. Junio C HamanoJan 15, 2017
  38. Jeff KingJan 16, 2017
  39. 00/27 Revamp the attribute system; another roundBrandon Williams, Jan 23, 2017
  40. 01/27 commit.c: use strchrnul() to scan for one lineBrandon Williams, Jan 23, 2017
  41. 02/27 attr.c: use strchrnul() to scan for one lineBrandon Williams, Jan 23, 2017
  42. 03/27 attr.c: update a stale comment on "struct match_attr"Brandon Williams, Jan 23, 2017
  43. 04/27 attr.c: explain the lack of attr-name syntax check in parse_attr()Brandon Williams, Jan 23, 2017
  44. 05/27 attr.c: complete a sentence in a commentBrandon Williams, Jan 23, 2017
  45. 07/27 attr.c: simplify macroexpand_one()Brandon Williams, Jan 23, 2017
  46. 10/27 attr: support quoting pathname patterns in C styleBrandon Williams, Jan 23, 2017
  47. 12/27 Documentation: fix a typoBrandon Williams, Jan 23, 2017
  48. 13/27 attr.c: outline the future plans by heavily commentingBrandon Williams, Jan 23, 2017
  49. 09/27 attr.c: plug small leak in parse_attr_line()Brandon Williams, Jan 23, 2017
  50. 11/27 attr.c: add push_stack() helperBrandon Williams, Jan 23, 2017
  51. 14/27 attr: rename function and struct related to checking attributesBrandon Williams, Jan 23, 2017
  52. 20/27 attr: change validity check for attribute names to use positive logicBrandon Williams, Jan 23, 2017
  53. 21/27 attr: use hashmap for attribute dictionaryBrandon Williams, Jan 23, 2017
  54. 22/27 attr: eliminate global check_all_attr arrayBrandon Williams, Jan 23, 2017
  55. Junio C HamanoJan 23, 2017
  56. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 23, 2017
  57. 23/27 attr: remove maybe-real, maybe-macro from git_attrBrandon Williams, Jan 23, 2017
  58. 24/27 attr: tighten const correctness with git_attr and match_attrBrandon Williams, Jan 23, 2017
  59. 17/27 attr: convert git_check_attrs() callers to use the new APIBrandon Williams, Jan 23, 2017
  60. 18/27 attr: retire git_check_attrs() APIBrandon Williams, Jan 23, 2017
  61. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 23, 2017
  62. 06/27 attr.c: mark where #if DEBUG ends more clearlyBrandon Williams, Jan 23, 2017
  63. 08/27 attr.c: tighten constness around "git_attr" structureBrandon Williams, Jan 23, 2017
  64. 19/27 attr: pass struct attr_check to collect_some_attrsBrandon Williams, Jan 23, 2017
  65. 26/27 attr: push the bare repo check into read_attr()Brandon Williams, Jan 23, 2017
  66. 27/27 attr: reformat git_attr_set_direction() functionBrandon Williams, Jan 23, 2017
  67. 25/27 attr: store attribute stack in attr_check structureBrandon Williams, Jan 23, 2017
  68. Junio C HamanoJan 23, 2017
  69. Brandon WilliamsJan 23, 2017
  70. Brandon WilliamsJan 24, 2017
  71. Junio C HamanoJan 24, 2017
  72. Brandon WilliamsJan 25, 2017
  73. Stefan BellerJan 25, 2017
  74. Junio C HamanoJan 25, 2017
  75. Brandon WilliamsJan 25, 2017
  76. Brandon WilliamsJan 25, 2017
  77. 00/27 Revamp the attribute system; another roundBrandon Williams, Jan 28, 2017
  78. 01/27 commit.c: use strchrnul() to scan for one lineBrandon Williams, Jan 28, 2017
  79. 02/27 attr.c: use strchrnul() to scan for one lineBrandon Williams, Jan 28, 2017
  80. 05/27 attr.c: complete a sentence in a commentBrandon Williams, Jan 28, 2017
  81. 03/27 attr.c: update a stale comment on "struct match_attr"Brandon Williams, Jan 28, 2017
  82. 07/27 attr.c: simplify macroexpand_one()Brandon Williams, Jan 28, 2017
  83. 06/27 attr.c: mark where #if DEBUG ends more clearlyBrandon Williams, Jan 28, 2017
  84. 08/27 attr.c: tighten constness around "git_attr" structureBrandon Williams, Jan 28, 2017
  85. 04/27 attr.c: explain the lack of attr-name syntax check in parse_attr()Brandon Williams, Jan 28, 2017
  86. 09/27 attr.c: plug small leak in parse_attr_line()Brandon Williams, Jan 28, 2017
  87. 10/27 attr: support quoting pathname patterns in C styleBrandon Williams, Jan 28, 2017
  88. 11/27 attr.c: add push_stack() helperBrandon Williams, Jan 28, 2017
  89. 12/27 Documentation: fix a typoBrandon Williams, Jan 28, 2017
  90. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 28, 2017
  91. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 30, 2017
  92. 13/27 attr.c: outline the future plans by heavily commentingBrandon Williams, Jan 28, 2017
  93. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 28, 2017
  94. Stefan BellerJan 28, 2017
  95. Brandon WilliamsJan 29, 2017
  96. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 30, 2017
  97. 14/27 attr: rename function and struct related to checking attributesBrandon Williams, Jan 28, 2017
  98. 18/27 attr: retire git_check_attrs() APIBrandon Williams, Jan 28, 2017
  99. 19/27 attr: pass struct attr_check to collect_some_attrsBrandon Williams, Jan 28, 2017
  100. 17/27 attr: convert git_check_attrs() callers to use the new APIBrandon Williams, Jan 28, 2017
  101. 22/27 attr: eliminate global check_all_attr arrayBrandon Williams, Jan 28, 2017
  102. 21/27 attr: use hashmap for attribute dictionaryBrandon Williams, Jan 28, 2017
  103. 26/27 attr: push the bare repo check into read_attr()Brandon Williams, Jan 28, 2017
  104. 25/27 attr: store attribute stack in attr_check structureBrandon Williams, Jan 28, 2017
  105. 20/27 attr: change validity check for attribute names to use positive logicBrandon Williams, Jan 28, 2017
  106. 24/27 attr: tighten const correctness with git_attr and match_attrBrandon Williams, Jan 28, 2017
  107. 27/27 attr: reformat git_attr_set_direction() functionBrandon Williams, Jan 28, 2017
  108. 23/27 attr: remove maybe-real, maybe-macro from git_attrBrandon Williams, Jan 28, 2017
  109. Junio C HamanoFeb 2, 2017
  110. Brandon WilliamsFeb 9, 2017
  111. Junio C HamanoFeb 9, 2017

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.