1 // Copyright 2014 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 #include <stddef.h>
6
7 #include "gn/build_settings.h"
8 #include "gn/err.h"
9 #include "gn/functions.h"
10 #include "gn/label_pattern.h"
11 #include "gn/parse_tree.h"
12 #include "gn/scope.h"
13 #include "gn/settings.h"
14 #include "gn/value.h"
15
16 namespace functions {
17
18 const char kLabelMatches[] = "label_matches";
19 const char kLabelMatches_HelpShort[] =
20 "label_matches: Returns whether a label matches any of a list of patterns.";
21 const char kLabelMatches_Help[] =
22 R"(label_matches: Returns true if the label matches any of a set of patterns.
23
24 label_matches(target_label, patterns)
25
26 The argument patterns must be a list of label patterns (see
27 "gn help label_pattern"). If the target_label matches any of the patterns,
28 the function returns the value true.
29
30 Examples
31 result = label_matches("//baz:bar", [ "//foo/bar/*", "//baz:*" ])
32 # result will be true
33 )";
34
RunLabelMatches(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)35 Value RunLabelMatches(Scope* scope,
36 const FunctionCallNode* function,
37 const std::vector<Value>& args,
38 Err* err) {
39 if (args.size() != 2) {
40 *err = Err(function, "Expecting exactly two arguments.");
41 return Value();
42 }
43
44 // Extract "label"
45 if (args[0].type() != Value::STRING) {
46 *err = Err(args[0], "First argument must be a target label.");
47 return Value();
48 }
49 Label label =
50 Label::Resolve(scope->GetSourceDir(),
51 scope->settings()->build_settings()->root_path_utf8(),
52 ToolchainLabelForScope(scope), args[0], err);
53 if (label.is_null()) {
54 return Value();
55 }
56
57 // Extract "patterns".
58 if (args[1].type() != Value::LIST) {
59 *err = Err(args[1], "Second argument must be a list of label patterns.");
60 return Value();
61 }
62 std::vector<LabelPattern> patterns;
63 patterns.reserve(args[1].list_value().size());
64
65 for (const auto& pattern_string : args[1].list_value()) {
66 if (pattern_string.type() != Value::STRING) {
67 *err = Err(pattern_string,
68 "Second argument must be a list of label patterns.");
69 return Value();
70 }
71 LabelPattern pattern = LabelPattern::GetPattern(
72 scope->GetSourceDir(),
73 scope->settings()->build_settings()->root_path_utf8(), pattern_string,
74 err);
75 if (err->has_error()) {
76 return Value();
77 }
78 patterns.push_back(std::move(pattern));
79 }
80
81 return Value(function, LabelPattern::VectorMatches(patterns, label));
82 }
83
84 } // namespace functions
85