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@xxxxxxxxx> --- Marius Storm-Olsen <marius@xxxxxxxxxxxxx> 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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html