File: match.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 (112 lines) | stat: -rw-r--r-- 3,201 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
101
102
103
104
105
106
107
108
109
110
111
112
/* Copyright 2013-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"

#include "make_unique.h"
#include "thirdparty/wildmatch/wildmatch.h"
#include <string>
using watchman::CaseSensitivity;

class WildMatchExpr : public QueryExpr {
  std::string pattern;
  CaseSensitivity caseSensitive;
  bool wholename;
  bool noescape;
  bool includedotfiles;

 public:
  WildMatchExpr(
      const char* pat,
      CaseSensitivity caseSensitive,
      bool wholename,
      bool noescape,
      bool includedotfiles)
      : pattern(pat),
        caseSensitive(caseSensitive),
        wholename(wholename),
        noescape(noescape),
        includedotfiles(includedotfiles) {}

  bool evaluate(struct w_query_ctx* ctx, const FileResult* file) override {
    w_string_piece str;
    bool res;

    if (wholename) {
      str = w_query_ctx_get_wholename(ctx);
    } else {
      str = file->baseName();
    }

#ifdef _WIN32
    // Translate to unix style slashes for wildmatch
    w_string normBuf = str.asWString().normalizeSeparators();
    str = normBuf;
#endif

    res = wildmatch(pattern.c_str(), str.data(),
                    (includedotfiles ? 0 : WM_PERIOD) |
                        (noescape ? WM_NOESCAPE : 0) |
                        (wholename ? WM_PATHNAME : 0) |
                        (caseSensitive == CaseSensitivity::CaseInSensitive
                             ? WM_CASEFOLD
                             : 0),
                    0) == WM_MATCH;

    return res;
  }

  static std::unique_ptr<QueryExpr>
  parse(w_query*, const json_ref& term, CaseSensitivity case_sensitive) {
    const char *ignore, *pattern, *scope = "basename";
    const char *which =
        case_sensitive == CaseSensitivity::CaseInSensitive ? "imatch" : "match";
    int noescape = 0;
    int includedotfiles = 0;

    if (json_unpack(
            term,
            "[s,s,s,{s?b,s?b}]",
            &ignore,
            &pattern,
            &scope,
            "noescape",
            &noescape,
            "includedotfiles",
            &includedotfiles) != 0 &&
        json_unpack(term, "[s,s,s]", &ignore, &pattern, &scope) != 0 &&
        json_unpack(term, "[s,s]", &ignore, &pattern) != 0) {
      throw QueryParseError(
          "Expected [\"", which, "\", \"pattern\", \"scope\"?]");
    }

    if (strcmp(scope, "basename") && strcmp(scope, "wholename")) {
      throw QueryParseError(
          "Invalid scope '", scope, "' for ", which, " expression");
    }

    return watchman::make_unique<WildMatchExpr>(
        pattern,
        case_sensitive,
        !strcmp(scope, "wholename"),
        noescape,
        includedotfiles);
  }
  static std::unique_ptr<QueryExpr> parseMatch(
      w_query* query,
      const json_ref& term) {
    return parse(query, term, query->case_sensitive);
  }
  static std::unique_ptr<QueryExpr> parseIMatch(
      w_query* query,
      const json_ref& term) {
    return parse(query, term, CaseSensitivity::CaseInSensitive);
  }
};
W_TERM_PARSER("match", WildMatchExpr::parseMatch)
W_TERM_PARSER("imatch", WildMatchExpr::parseIMatch)
W_CAP_REG("wildmatch")
W_CAP_REG("wildmatch-multislash")

/* vim:ts=2:sw=2:et:
 */