• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/err.h"
8 #include "gn/filesystem_utils.h"
9 #include "gn/functions.h"
10 #include "gn/parse_tree.h"
11 #include "gn/scope.h"
12 #include "gn/value.h"
13 
14 namespace functions {
15 
16 const char kFilterExclude[] = "filter_exclude";
17 const char kFilterExclude_HelpShort[] =
18     "filter_exclude: Remove values that match a set of patterns.";
19 const char kFilterExclude_Help[] =
20     R"(filter_exclude: Remove values that match a set of patterns.
21 
22   filter_exclude(values, exclude_patterns)
23 
24   The argument values must be a list of strings.
25 
26   The argument exclude_patterns must be a list of file patterns (see
27   "gn help file_pattern"). Any elements in values matching at least one
28   of those patterns will be excluded.
29 
30 Examples
31   values = [ "foo.cc", "foo.h", "foo.proto" ]
32   result = filter_exclude(values, [ "*.proto" ])
33   # result will be [ "foo.cc", "foo.h" ]
34 )";
35 
36 const char kFilterInclude[] = "filter_include";
37 const char kFilterInclude_HelpShort[] =
38     "filter_include: Remove values that do not match a set of patterns.";
39 const char kFilterInclude_Help[] =
40     R"(filter_include: Remove values that do not match a set of patterns.
41 
42   filter_include(values, include_patterns)
43 
44   The argument values must be a list of strings.
45 
46   The argument include_patterns must be a list of file patterns (see
47   "gn help file_pattern"). Only elements from values matching at least
48   one of the pattern will be included.
49 
50 Examples
51   values = [ "foo.cc", "foo.h", "foo.proto" ]
52   result = filter_include(values, [ "*.proto" ])
53   # result will be [ "foo.proto" ]
54 )";
55 
56 namespace {
57 
58 enum FilterSelection {
59   kExcludeFilter,
60   kIncludeFilter,
61 };
62 
RunFilter(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,FilterSelection selection,Err * err)63 Value RunFilter(Scope* scope,
64                 const FunctionCallNode* function,
65                 const std::vector<Value>& args,
66                 FilterSelection selection,
67                 Err* err) {
68   if (args.size() != 2) {
69     *err = Err(function, "Expecting exactly two arguments.");
70     return Value();
71   }
72 
73   // Extract "values".
74   if (args[0].type() != Value::LIST) {
75     *err = Err(args[0], "First argument must be a list of strings.");
76     return Value();
77   }
78 
79   // Extract "patterns".
80   PatternList patterns;
81   patterns.SetFromValue(args[1], err);
82   if (err->has_error())
83     return Value();
84 
85   Value result(function, Value::LIST);
86   for (const auto& value : args[0].list_value()) {
87     if (value.type() != Value::STRING) {
88       *err = Err(args[0], "First argument must be a list of strings.");
89       return Value();
90     }
91 
92     const bool matches_pattern = patterns.MatchesValue(value);
93     switch (selection) {
94       case kIncludeFilter:
95         if (matches_pattern)
96           result.list_value().push_back(value);
97         break;
98 
99       case kExcludeFilter:
100         if (!matches_pattern)
101           result.list_value().push_back(value);
102         break;
103     }
104   }
105   return result;
106 }
107 
108 }  // anonymous namespace
109 
RunFilterExclude(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)110 Value RunFilterExclude(Scope* scope,
111                        const FunctionCallNode* function,
112                        const std::vector<Value>& args,
113                        Err* err) {
114   return RunFilter(scope, function, args, kExcludeFilter, err);
115 }
116 
RunFilterInclude(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)117 Value RunFilterInclude(Scope* scope,
118                        const FunctionCallNode* function,
119                        const std::vector<Value>& args,
120                        Err* err) {
121   return RunFilter(scope, function, args, kIncludeFilter, err);
122 }
123 
124 }  // namespace functions
125