Unroll the loop over passes

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>

Michael Haggerty committed Aug 12, 2011 at 23:43 UTC d68e1c183c056ae583a45b610d086ac078886154
1 file changed +26 -25
attr.c
+26 -25
@@ -191,10 +191,9 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
191 int lineno, int macro_ok)
192 {
193 int namelen;
194 - int num_attr;
194 + int num_attr, i;
195 const char *cp, *name, *states;
196 struct match_attr *res = NULL;
197 - int pass;
197 int is_macro;
198
199 cp = line + strspn(line, blank);
@@ -226,30 +225,32 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
225 states = name + namelen;
226 states += strspn(states, blank);
227
229 - for (pass = 0; pass < 2; pass++) {
230 - /* pass 0 counts and allocates, pass 1 fills */
231 - for (cp = states, num_attr = 0; *cp; num_attr++) {
232 - cp = parse_attr(src, lineno, cp,
233 - pass ? &(res->state[num_attr]) : NULL);
234 - if (!cp)
235 - return NULL;
236 - }
237 - if (pass)
238 - break;
239 - res = xcalloc(1,
240 - sizeof(*res) +
241 - sizeof(struct attr_state) * num_attr +
242 - (is_macro ? 0 : namelen + 1));
243 - if (is_macro)
244 - res->u.attr = git_attr_internal(name, namelen);
245 - else {
246 - res->u.pattern = (char *)&(res->state[num_attr]);
247 - memcpy(res->u.pattern, name, namelen);
248 - res->u.pattern[namelen] = 0;
249 - }
250 - res->is_macro = is_macro;
251 - res->num_attr = num_attr;
228 + /* First pass to count the attr_states */
229 + for (cp = states, num_attr = 0; *cp; num_attr++) {
230 + cp = parse_attr(src, lineno, cp, NULL);
231 + if (!cp)
232 + return NULL;
233 }
234 +
235 + res = xcalloc(1,
236 + sizeof(*res) +
237 + sizeof(struct attr_state) * num_attr +
238 + (is_macro ? 0 : namelen + 1));
239 + if (is_macro)
240 + res->u.attr = git_attr_internal(name, namelen);
241 + else {
242 + res->u.pattern = (char *)&(res->state[num_attr]);
243 + memcpy(res->u.pattern, name, namelen);
244 + res->u.pattern[namelen] = 0;
245 + }
246 + res->is_macro = is_macro;
247 + res->num_attr = num_attr;
248 +
249 + /* Second pass to fill the attr_states */
250 + for (cp = states, i = 0; *cp; i++) {
251 + cp = parse_attr(src, lineno, cp, &(res->state[i]));
252 + }
253 +
254 return res;
255 }
256