forked from facebook/watchman
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ignore.cpp
100 lines (81 loc) · 2.62 KB
/
ignore.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* Copyright 2016-present Facebook, Inc.
* Licensed under the Apache License, Version 2.0 */
#include "watchman.h"
// The path and everything below it is ignored.
#define FULL_IGNORE 0x1
// The grand-children of the path are ignored, but not the path
// or its direct children.
#define VCS_IGNORE 0x2
void watchman_ignore::add(const w_string& path, bool is_vcs_ignore) {
(is_vcs_ignore ? ignore_vcs : ignore_dirs).insert(path);
tree.insert(path, is_vcs_ignore ? VCS_IGNORE : FULL_IGNORE);
if (!is_vcs_ignore) {
dirs_vec.push_back(path);
}
}
bool watchman_ignore::isIgnored(const char* path, uint32_t pathlen) const {
const char *skip_prefix;
uint32_t len;
auto leaf = tree.longestMatch((const unsigned char*)path, (int)pathlen);
if (!leaf) {
// No entry -> not ignored.
return false;
}
if (pathlen < leaf->key.size()) {
// We wanted "buil" but matched "build"
return false;
}
if (pathlen == leaf->key.size()) {
// Exact match. This is an ignore if we are in FULL_IGNORE,
// but not in VCS_IGNORE mode.
return leaf->value == FULL_IGNORE ? true : false;
}
// Our input string was longer than the leaf key string.
// We need to ensure that we observe a directory separator at the
// character after the common prefix, otherwise we may be falsely
// matching a sibling entry.
skip_prefix = path + leaf->key.size();
len = pathlen - leaf->key.size();
if (!is_slash(*skip_prefix)) {
// we wanted "foo/bar" but we matched something like "food"
// this is not an ignore situation.
return false;
}
if (leaf->value == FULL_IGNORE) {
// Definitely ignoring this portion of the tree
return true;
}
// we need to apply vcs_ignore style logic to determine if we are ignoring
// this path. This devolves to: "is there a '/' character after the end of
// the leaf key prefix?"
if (pathlen <= leaf->key.size()) {
// There can't be a slash after this portion of the tree, therefore
// this is not ignored.
return false;
}
// Skip over the '/'
skip_prefix++;
len--;
#ifndef _WIN32
// If we find a '/' from this point, we are ignoring this path.
return memchr(skip_prefix, '/', len) != nullptr;
#else
// On windows, both '/' and '\' are possible.
while (len > 0) {
if (is_slash(*skip_prefix)) {
return true;
}
skip_prefix++;
len--;
}
return false;
#endif
}
bool watchman_ignore::isIgnoreVCS(const w_string& path) const {
return ignore_vcs.find(path) != ignore_vcs.end();
}
bool watchman_ignore::isIgnoreDir(const w_string& path) const {
return ignore_dirs.find(path) != ignore_dirs.end();
}
/* vim:ts=2:sw=2:et:
*/