1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef TOOLS_GN_PATTERN_H_
6#define TOOLS_GN_PATTERN_H_
7
8#include <string>
9#include <vector>
10
11#include "tools/gn/value.h"
12
13class Pattern {
14 public:
15  struct Subrange {
16    enum Type {
17      LITERAL,  // Matches exactly the contents of the string.
18      ANYTHING,  // * (zero or more chars).
19      PATH_BOUNDARY  // '/' or beginning of string.
20    };
21
22    Subrange(Type t, const std::string& l = std::string())
23        : type(t),
24          literal(l) {
25    }
26
27    // Returns the minimum number of chars that this subrange requires.
28    size_t MinSize() const {
29      switch (type) {
30        case LITERAL:
31          return literal.size();
32        case ANYTHING:
33          return 0;
34        case PATH_BOUNDARY:
35          return 0;  // Can match beginning or end of string, which is 0 len.
36        default:
37          return 0;
38      }
39    }
40
41    Type type;
42
43    // When type == LITERAL this is the text to match.
44    std::string literal;
45  };
46
47  Pattern(const std::string& s);
48  ~Pattern();
49
50  // Returns true if the current pattern matches the given string.
51  bool MatchesString(const std::string& s) const;
52
53 private:
54  // allow_implicit_path_boundary determines if a path boundary should accept
55  // matches at the beginning or end of the string.
56  bool RecursiveMatch(const std::string& s,
57                      size_t begin_char,
58                      size_t subrange_index,
59                      bool allow_implicit_path_boundary) const;
60
61  std::vector<Subrange> subranges_;
62
63  // Set to true when the subranges are "*foo" ("ANYTHING" followed by a
64  // literal). This covers most patterns so we optimize for this.
65  bool is_suffix_;
66};
67
68class PatternList {
69 public:
70  PatternList();
71  ~PatternList();
72
73  bool is_empty() const { return patterns_.empty(); }
74
75  void Append(const Pattern& pattern);
76
77  // Initializes the pattern list from a give list of pattern strings. Sets
78  // |*err| on failure.
79  void SetFromValue(const Value& v, Err* err);
80
81  bool MatchesString(const std::string& s) const;
82  bool MatchesValue(const Value& v) const;
83
84 private:
85  std::vector<Pattern> patterns_;
86};
87
88#endif  // TOOLS_GN_PATTERN_H_
89