126
void add_exclude(const char *string, const char *base,
127
int baselen, struct exclude_list *which)
128
{
129
- struct exclude *x = xmalloc(sizeof (*x));
129
+ struct exclude *x;
130
+ size_t len;
131
+ int to_exclude = 1;
132
+ int flags = 0;
133
131
- x->to_exclude = 1;
134
if (*string == '!') {
133
- x->to_exclude = 0;
135
+ to_exclude = 0;
136
string++;
137
}
136
- x->pattern = string;
138
+ len = strlen(string);
139
+ if (len && string[len - 1] == '/') {
140
+ char *s;
141
+ x = xmalloc(sizeof(*x) + len);
142
+ s = (char*)(x+1);
143
+ memcpy(s, string, len - 1);
144
+ s[len - 1] = '\0';
145
+ string = s;
146
+ x->pattern = s;
147
+ flags = EXC_FLAG_MUSTBEDIR;
148
+ } else {
149
+ x = xmalloc(sizeof(*x));
150
+ x->pattern = string;
151
+ }
152
+ x->to_exclude = to_exclude;
153
x->patternlen = strlen(string);
154
x->base = base;
155
x->baselen = baselen;
140
- x->flags = 0;
156
+ x->flags = flags;
157
if (!strchr(string, '/'))
158
x->flags |= EXC_FLAG_NODIR;
159
if (no_wildcard(string))
277
* Return 1 for exclude, 0 for include and -1 for undecided.
278
*/
279
static int excluded_1(const char *pathname,
264
- int pathlen, const char *basename,
280
+ int pathlen, const char *basename, int dtype,
281
struct exclude_list *el)
282
{
283
int i;
288
const char *exclude = x->pattern;
289
int to_exclude = x->to_exclude;
290
291
+ if ((x->flags & EXC_FLAG_MUSTBEDIR) &&
292
+ (dtype != DT_DIR))
293
+ continue;
294
+
295
if (x->flags & EXC_FLAG_NODIR) {
296
/* match basename */
297
if (x->flags & EXC_FLAG_NOWILDCARD) {
334
return -1; /* undecided */
335
}
336
317
-int excluded(struct dir_struct *dir, const char *pathname)
337
+int excluded(struct dir_struct *dir, const char *pathname, int dtype)
338
{
339
int pathlen = strlen(pathname);
340
int st;
343
344
prep_exclude(dir, pathname, basename-pathname);
345
for (st = EXC_CMDL; st <= EXC_FILE; st++) {
326
- switch (excluded_1(pathname, pathlen, basename, &dir->exclude_list[st])) {
346
+ switch (excluded_1(pathname, pathlen, basename,
347
+ dtype, &dir->exclude_list[st])) {
348
case 0:
349
return 0;
350
case 1:
581
if (simplify_away(fullname, baselen + len, simplify))
582
continue;
583
563
- exclude = excluded(dir, fullname);
584
+ dtype = get_dtype(de, fullname);
585
+ exclude = excluded(dir, fullname, dtype);
586
if (exclude && dir->collect_ignored
587
&& in_pathspec(fullname, baselen + len, simplify))
588
dir_add_ignored(dir, fullname, baselen + len);
594
if (exclude && !dir->show_ignored)
595
continue;
596
575
- dtype = get_dtype(de, fullname);
576
-
597
/*
598
* Do we want to see just the ignored files?
599
* We still need to recurse into directories,