gitignore: make pattern parsing code a separate function

This function can later be reused by attr.c. Also turn to_exclude field into a flag. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Oct 15, 2012 at 13:24 UTC 84460eec8dcc82417840bf4be2eb0c13d14b1c94
2 files changed +50 -23
dir.c
+49 -22
@@ -308,42 +308,69 @@ static int no_wildcard(const char *string)
308 return string[simple_length(string)] == '\0';
309 }
310
311 +static void parse_exclude_pattern(const char **pattern,
312 + int *patternlen,
313 + int *flags,
314 + int *nowildcardlen)
315 +{
316 + const char *p = *pattern;
317 + size_t i, len;
318 +
319 + *flags = 0;
320 + if (*p == '!') {
321 + *flags |= EXC_FLAG_NEGATIVE;
322 + p++;
323 + }
324 + len = strlen(p);
325 + if (len && p[len - 1] == '/') {
326 + len--;
327 + *flags |= EXC_FLAG_MUSTBEDIR;
328 + }
329 + for (i = 0; i < len; i++) {
330 + if (p[i] == '/')
331 + break;
332 + }
333 + if (i == len)
334 + *flags |= EXC_FLAG_NODIR;
335 + *nowildcardlen = simple_length(p);
336 + /*
337 + * we should have excluded the trailing slash from 'p' too,
338 + * but that's one more allocation. Instead just make sure
339 + * nowildcardlen does not exceed real patternlen
340 + */
341 + if (*nowildcardlen > len)
342 + *nowildcardlen = len;
343 + if (*p == '*' && no_wildcard(p + 1))
344 + *flags |= EXC_FLAG_ENDSWITH;
345 + *pattern = p;
346 + *patternlen = len;
347 +}
348 +
349 void add_exclude(const char *string, const char *base,
350 int baselen, struct exclude_list *which)
351 {
352 struct exclude *x;
315 - size_t len;
316 - int to_exclude = 1;
317 - int flags = 0;
353 + int patternlen;
354 + int flags;
355 + int nowildcardlen;
356
319 - if (*string == '!') {
320 - to_exclude = 0;
321 - string++;
322 - }
323 - len = strlen(string);
324 - if (len && string[len - 1] == '/') {
357 + parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen);
358 + if (flags & EXC_FLAG_MUSTBEDIR) {
359 char *s;
326 - x = xmalloc(sizeof(*x) + len);
360 + x = xmalloc(sizeof(*x) + patternlen + 1);
361 s = (char *)(x+1);
328 - memcpy(s, string, len - 1);
329 - s[len - 1] = '\0';
330 - string = s;
362 + memcpy(s, string, patternlen);
363 + s[patternlen] = '\0';
364 x->pattern = s;
332 - flags = EXC_FLAG_MUSTBEDIR;
365 } else {
366 x = xmalloc(sizeof(*x));
367 x->pattern = string;
368 }
337 - x->to_exclude = to_exclude;
338 - x->patternlen = strlen(string);
369 + x->patternlen = patternlen;
370 + x->nowildcardlen = nowildcardlen;
371 x->base = base;
372 x->baselen = baselen;
373 x->flags = flags;
342 - if (!strchr(string, '/'))
343 - x->flags |= EXC_FLAG_NODIR;
344 - x->nowildcardlen = simple_length(string);
345 - if (*string == '*' && no_wildcard(string+1))
346 - x->flags |= EXC_FLAG_ENDSWITH;
374 ALLOC_GROW(which->excludes, which->nr + 1, which->alloc);
375 which->excludes[which->nr++] = x;
376 }
@@ -584,7 +611,7 @@ int excluded_from_list(const char *pathname,
611 for (i = el->nr - 1; 0 <= i; i--) {
612 struct exclude *x = el->excludes[i];
613 const char *exclude = x->pattern;
587 - int to_exclude = x->to_exclude;
614 + int to_exclude = x->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
615 int prefix = x->nowildcardlen;
616
617 if (x->flags & EXC_FLAG_MUSTBEDIR) {
dir.h
+1 -1
@@ -11,6 +11,7 @@ struct dir_entry {
11 #define EXC_FLAG_NODIR 1
12 #define EXC_FLAG_ENDSWITH 4
13 #define EXC_FLAG_MUSTBEDIR 8
14 +#define EXC_FLAG_NEGATIVE 16
15
16 struct exclude_list {
17 int nr;
@@ -21,7 +22,6 @@ struct exclude_list {
22 int nowildcardlen;
23 const char *base;
24 int baselen;
24 - int to_exclude;
25 int flags;
26 } **excludes;
27 };