Skip to content

Commit

Permalink
Unroll the loop over passes
Browse files Browse the repository at this point in the history
The passes no longer share much code, and the unrolled code is easier
to understand.

Use a new index variable instead of num_attr for the second loop, as
we are no longer counting attributes but rather indexing through them.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
mhagger authored and gitster committed Aug 14, 2011
1 parent e0a5f9a commit d68e1c1
Showing 1 changed file with 26 additions and 25 deletions.
51 changes: 26 additions & 25 deletions attr.c
Expand Up @@ -191,10 +191,9 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
int lineno, int macro_ok)
{
int namelen;
int num_attr;
int num_attr, i;
const char *cp, *name, *states;
struct match_attr *res = NULL;
int pass;
int is_macro;

cp = line + strspn(line, blank);
Expand Down Expand Up @@ -226,30 +225,32 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
states = name + namelen;
states += strspn(states, blank);

for (pass = 0; pass < 2; pass++) {
/* pass 0 counts and allocates, pass 1 fills */
for (cp = states, num_attr = 0; *cp; num_attr++) {
cp = parse_attr(src, lineno, cp,
pass ? &(res->state[num_attr]) : NULL);
if (!cp)
return NULL;
}
if (pass)
break;
res = xcalloc(1,
sizeof(*res) +
sizeof(struct attr_state) * num_attr +
(is_macro ? 0 : namelen + 1));
if (is_macro)
res->u.attr = git_attr_internal(name, namelen);
else {
res->u.pattern = (char *)&(res->state[num_attr]);
memcpy(res->u.pattern, name, namelen);
res->u.pattern[namelen] = 0;
}
res->is_macro = is_macro;
res->num_attr = num_attr;
/* First pass to count the attr_states */
for (cp = states, num_attr = 0; *cp; num_attr++) {
cp = parse_attr(src, lineno, cp, NULL);
if (!cp)
return NULL;
}

res = xcalloc(1,
sizeof(*res) +
sizeof(struct attr_state) * num_attr +
(is_macro ? 0 : namelen + 1));
if (is_macro)
res->u.attr = git_attr_internal(name, namelen);
else {
res->u.pattern = (char *)&(res->state[num_attr]);
memcpy(res->u.pattern, name, namelen);
res->u.pattern[namelen] = 0;
}
res->is_macro = is_macro;
res->num_attr = num_attr;

/* Second pass to fill the attr_states */
for (cp = states, i = 0; *cp; i++) {
cp = parse_attr(src, lineno, cp, &(res->state[i]));
}

return res;
}

Expand Down

0 comments on commit d68e1c1

Please sign in to comment.