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

[PATCH 1/2] attr.c: refactoring

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 14, 2007, 08:40 UTC
Message-ID
<7v1we6ecfm.fsf_-_@assigned-by-dhcp.cox.net>
In-Reply-To
<46BFFB1A.4070704@trolltech.com>

This splits out a common routine that parses a single line of attribute file and adds it to the attr_stack. It should not change any behaviour, other than attrs array in the attr_stack structure is now grown with alloc_nr() macro, instead of one by one, which relied on xrealloc() to give enough slack to be efficient enough.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Marius Storm-Olsen <marius@trolltech.com> writes:
 >> This essentially treats not having .gitattributes files checked
 >> out as equivalent to having these files checked out unmodified,
 >> which is very much in line with how the world is designed to
 >> work.
 >
 > ACK! We really need this! :-)
 So this is the first part, which does not do much.  The second
 one is interesting.
 attr.c |   67 +++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/attr.c b/attr.c
index a071254..8d778f1 100644
--- a/attr.c
+++ b/attr.c
@@ -257,6 +257,7 @@ static struct attr_stack {
 	struct attr_stack *prev;
 	char *origin;
 	unsigned num_matches;
+	unsigned alloc;
 	struct match_attr **attrs;
 } *attr_stack;
 
@@ -287,6 +288,26 @@ static const char *builtin_attr[] = {
 	NULL,
 };
 
+static void handle_attr_line(struct attr_stack *res,
+			     const char *line,
+			     const char *src,
+			     int lineno,
+			     int macro_ok)
+{
+	struct match_attr *a;
+
+	a = parse_attr_line(line, src, lineno, macro_ok);
+	if (!a)
+		return;
+	if (res->alloc <= res->num_matches) {
+		res->alloc = alloc_nr(res->num_matches);
+		res->attrs = xrealloc(res->attrs,
+				      sizeof(struct match_attr *) *
+				      res->alloc);
+	}
+	res->attrs[res->num_matches++] = a;
+}
+
 static struct attr_stack *read_attr_from_array(const char **list)
 {
 	struct attr_stack *res;
@@ -294,42 +315,34 @@ static struct attr_stack *read_attr_from_array(const char **list)
 	int lineno = 0;
 
 	res = xcalloc(1, sizeof(*res));
-	while ((line = *(list++)) != NULL) {
-		struct match_attr *a;
-
-		a = parse_attr_line(line, "[builtin]", ++lineno, 1);
-		if (!a)
-			continue;
-		res->attrs = xrealloc(res->attrs,
-			sizeof(struct match_attr *) * (res->num_matches + 1));
-		res->attrs[res->num_matches++] = a;
-	}
+	while ((line = *(list++)) != NULL)
+		handle_attr_line(res, line, "[builtin]", ++lineno, 1);
 	return res;
 }
 
 static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
 {
-	FILE *fp;
+	FILE *fp = fopen(path, "r");
 	struct attr_stack *res;
 	char buf[2048];
 	int lineno = 0;
 
-	res = xcalloc(1, sizeof(*res));
-	fp = fopen(path, "r");
 	if (!fp)
-		return res;
+		return NULL;
+	res = xcalloc(1, sizeof(*res));
+	while (fgets(buf, sizeof(buf), fp))
+		handle_attr_line(res, buf, path, ++lineno, macro_ok);
+	fclose(fp);
+	return res;
+}
 
-	while (fgets(buf, sizeof(buf), fp)) {
-		struct match_attr *a;
+static struct attr_stack *read_attr(const char *path, int macro_ok)
+{
+	struct attr_stack *res;
 
-		a = parse_attr_line(buf, path, ++lineno, macro_ok);
-		if (!a)
-			continue;
-		res->attrs = xrealloc(res->attrs,
-			sizeof(struct match_attr *) * (res->num_matches + 1));
-		res->attrs[res->num_matches++] = a;
-	}
-	fclose(fp);
+	res = read_attr_from_file(path, macro_ok);
+	if (!res)
+		res = xcalloc(1, sizeof(*res));
 	return res;
 }
 
@@ -370,13 +383,15 @@ static void bootstrap_attr_stack(void)
 		elem->prev = attr_stack;
 		attr_stack = elem;
 
-		elem = read_attr_from_file(GITATTRIBUTES_FILE, 1);
+		elem = read_attr(GITATTRIBUTES_FILE, 1);
 		elem->origin = strdup("");
 		elem->prev = attr_stack;
 		attr_stack = elem;
 		debug_push(elem);
 
 		elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
+		if (!elem)
+			elem = xcalloc(1, sizeof(*elem));
 		elem->origin = NULL;
 		elem->prev = attr_stack;
 		attr_stack = elem;
@@ -441,7 +456,7 @@ static void prepare_attr_stack(const char *path, int dirlen)
 		memcpy(pathbuf + dirlen, "/", 2);
 		cp = strchr(pathbuf + len + 1, '/');
 		strcpy(cp + 1, GITATTRIBUTES_FILE);
-		elem = read_attr_from_file(pathbuf, 0);
+		elem = read_attr(pathbuf, 0);
 		*cp = '\0';
 		elem->origin = strdup(pathbuf);
 		elem->prev = attr_stack;
-- 
1.5.3.rc4.89.g18078
Previous: Dmitry KakurinNext: Junio C Hamano
Message 13 of 20 in “attr: fix attribute handling if .gitattributes is involved”
  1. 1/2 attr: fix attribute handling if .gitattributes is involvedSteffen Prohaska, Aug 12, 2007
  2. 2/2 checkout: fix attribute handling in checkout allSteffen Prohaska, Aug 12, 2007
  3. Junio C HamanoAug 12, 2007
  4. Steffen ProhaskaAug 12, 2007
  5. Junio C HamanoAug 13, 2007
  6. Marius Storm-OlsenAug 13, 2007
  7. Steffen ProhaskaAug 13, 2007
  8. Marius Storm-OlsenAug 13, 2007
  9. Steffen ProhaskaAug 13, 2007
  10. Marius Storm-OlsenAug 13, 2007
  11. Steffen ProhaskaAug 13, 2007
  12. Dmitry KakurinAug 13, 2007
  13. 1/2 attr.c: refactoringJunio C Hamano, Aug 14, 2007
  14. 2/2 attr.c: read .gitattributes from index as well.Junio C Hamano, Aug 14, 2007
  15. Steffen ProhaskaAug 13, 2007
  16. Johannes SchindelinAug 13, 2007
  17. David KastrupAug 13, 2007
  18. git-update-ref bug? (was: [PATCH 2/2] checkout: fix attribute handling in checkout all)David Kastrup, Aug 13, 2007
  19. Junio C HamanoAug 13, 2007
  20. Brian DowningAug 13, 2007

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.