File: ignore.cpp

package info (click to toggle)
watchman 4.9.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,992 kB
  • sloc: cpp: 27,459; python: 6,538; java: 3,404; php: 3,257; ansic: 2,803; javascript: 1,116; makefile: 671; ruby: 364; sh: 124; xml: 102; lisp: 4
file content (100 lines) | stat: -rw-r--r-- 2,681 bytes parent folder | download | duplicates (3)
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:
 */