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 "gn/substitution_type.h"
6
7 #include <stddef.h>
8 #include <stdlib.h>
9
10 #include "gn/c_substitution_type.h"
11 #include "gn/err.h"
12 #include "gn/rust_substitution_type.h"
13
14 const std::vector<SubstitutionTypes*> AllSubstitutions = {
15 &GeneralSubstitutions, &CSubstitutions, &RustSubstitutions};
16
17 const SubstitutionTypes GeneralSubstitutions = {
18 &SubstitutionLiteral,
19
20 &SubstitutionOutput,
21 &SubstitutionLabel,
22 &SubstitutionLabelName,
23 &SubstitutionRootGenDir,
24 &SubstitutionRootOutDir,
25 &SubstitutionOutputDir,
26 &SubstitutionOutputExtension,
27 &SubstitutionTargetGenDir,
28 &SubstitutionTargetOutDir,
29 &SubstitutionTargetOutputName,
30
31 &SubstitutionSource,
32 &SubstitutionSourceNamePart,
33 &SubstitutionSourceFilePart,
34 &SubstitutionSourceDir,
35 &SubstitutionSourceRootRelativeDir,
36 &SubstitutionSourceGenDir,
37 &SubstitutionSourceOutDir,
38 &SubstitutionSourceTargetRelative,
39
40 &SubstitutionBundleRootDir,
41 &SubstitutionBundleContentsDir,
42 &SubstitutionBundleResourcesDir,
43 &SubstitutionBundleExecutableDir,
44
45 &SubstitutionBundleProductType,
46 &SubstitutionBundlePartialInfoPlist,
47
48 &SubstitutionRspFileName,
49 };
50
51 const Substitution SubstitutionLiteral = {"<<literal>>", nullptr};
52
53 const Substitution SubstitutionSource = {"{{source}}", "in"};
54 const Substitution SubstitutionOutput = {"{{output}}", "out"};
55
56 const Substitution SubstitutionSourceNamePart = {"{{source_name_part}}",
57 "source_name_part"};
58 const Substitution SubstitutionSourceFilePart = {"{{source_file_part}}",
59 "source_file_part"};
60 const Substitution SubstitutionSourceDir = {"{{source_dir}}", "source_dir"};
61 const Substitution SubstitutionSourceRootRelativeDir = {
62 "{{source_root_relative_dir}}", "source_root_relative_dir"};
63 const Substitution SubstitutionSourceGenDir = {"{{source_gen_dir}}",
64 "source_gen_dir"};
65 const Substitution SubstitutionSourceOutDir = {"{{source_out_dir}}",
66 "source_out_dir"};
67 const Substitution SubstitutionSourceTargetRelative = {
68 "{{source_target_relative}}", "source_target_relative"};
69
70 // Valid for all compiler and linker tools. These depend on the target and
71 // do not vary on a per-file basis.
72 const Substitution SubstitutionLabel = {"{{label}}", "label"};
73 const Substitution SubstitutionLabelName = {"{{label_name}}", "label_name"};
74 const Substitution SubstitutionRootGenDir = {"{{root_gen_dir}}",
75 "root_gen_dir"};
76 const Substitution SubstitutionRootOutDir = {"{{root_out_dir}}",
77 "root_out_dir"};
78 const Substitution SubstitutionOutputDir = {"{{output_dir}}", "output_dir"};
79 const Substitution SubstitutionOutputExtension = {"{{output_extension}}",
80 "output_extension"};
81 const Substitution SubstitutionTargetGenDir = {"{{target_gen_dir}}",
82 "target_gen_dir"};
83 const Substitution SubstitutionTargetOutDir = {"{{target_out_dir}}",
84 "target_out_dir"};
85 const Substitution SubstitutionTargetOutputName = {"{{target_output_name}}",
86 "target_output_name"};
87
88 // Valid for bundle_data targets.
89 const Substitution SubstitutionBundleRootDir = {"{{bundle_root_dir}}",
90 "bundle_root_dir"};
91 const Substitution SubstitutionBundleContentsDir = {"{{bundle_contents_dir}}",
92 "bundle_contents_dir"};
93 const Substitution SubstitutionBundleResourcesDir = {"{{bundle_resources_dir}}",
94 "bundle_resources_dir"};
95 const Substitution SubstitutionBundleExecutableDir = {
96 "{{bundle_executable_dir}}", "bundle_executable_dir"};
97
98 // Valid for compile_xcassets tool.
99 const Substitution SubstitutionBundleProductType = {"{{bundle_product_type}}",
100 "product_type"};
101 const Substitution SubstitutionBundlePartialInfoPlist = {
102 "{{bundle_partial_info_plist}}", "partial_info_plist"};
103
104 // Used only for the args of actions.
105 const Substitution SubstitutionRspFileName = {"{{response_file_name}}",
106 "rspfile"};
107
108 SubstitutionBits::SubstitutionBits() = default;
109
MergeFrom(const SubstitutionBits & other)110 void SubstitutionBits::MergeFrom(const SubstitutionBits& other) {
111 for (const Substitution* s : other.used)
112 used.insert(s);
113 }
114
FillVector(std::vector<const Substitution * > * vect) const115 void SubstitutionBits::FillVector(
116 std::vector<const Substitution*>* vect) const {
117 for (const Substitution* s : used) {
118 vect->push_back(s);
119 }
120 }
121
SubstitutionIsInOutputDir(const Substitution * type)122 bool SubstitutionIsInOutputDir(const Substitution* type) {
123 return type == &SubstitutionSourceGenDir ||
124 type == &SubstitutionSourceOutDir || type == &SubstitutionRootGenDir ||
125 type == &SubstitutionRootOutDir || type == &SubstitutionTargetGenDir ||
126 type == &SubstitutionTargetOutDir;
127 }
128
SubstitutionIsInBundleDir(const Substitution * type)129 bool SubstitutionIsInBundleDir(const Substitution* type) {
130 return type == &SubstitutionBundleRootDir ||
131 type == &SubstitutionBundleContentsDir ||
132 type == &SubstitutionBundleResourcesDir ||
133 type == &SubstitutionBundleExecutableDir;
134 }
135
IsValidBundleDataSubstitution(const Substitution * type)136 bool IsValidBundleDataSubstitution(const Substitution* type) {
137 return type == &SubstitutionLiteral ||
138 type == &SubstitutionSourceTargetRelative ||
139 type == &SubstitutionSourceNamePart ||
140 type == &SubstitutionSourceFilePart ||
141 type == &SubstitutionSourceRootRelativeDir ||
142 type == &SubstitutionBundleRootDir ||
143 type == &SubstitutionBundleContentsDir ||
144 type == &SubstitutionBundleResourcesDir ||
145 type == &SubstitutionBundleExecutableDir;
146 }
147
IsValidSourceSubstitution(const Substitution * type)148 bool IsValidSourceSubstitution(const Substitution* type) {
149 return type == &SubstitutionLiteral || type == &SubstitutionSource ||
150 type == &SubstitutionSourceNamePart ||
151 type == &SubstitutionSourceFilePart ||
152 type == &SubstitutionSourceDir ||
153 type == &SubstitutionSourceRootRelativeDir ||
154 type == &SubstitutionSourceGenDir ||
155 type == &SubstitutionSourceOutDir ||
156 type == &SubstitutionSourceTargetRelative;
157 }
158
IsValidScriptArgsSubstitution(const Substitution * type)159 bool IsValidScriptArgsSubstitution(const Substitution* type) {
160 return IsValidSourceSubstitution(type) || type == &SubstitutionRspFileName;
161 }
162
IsValidToolSubstitution(const Substitution * type)163 bool IsValidToolSubstitution(const Substitution* type) {
164 return type == &SubstitutionLiteral || type == &SubstitutionOutput ||
165 type == &SubstitutionLabel || type == &SubstitutionLabelName ||
166 type == &SubstitutionRootGenDir || type == &SubstitutionRootOutDir ||
167 type == &SubstitutionTargetGenDir ||
168 type == &SubstitutionTargetOutDir ||
169 type == &SubstitutionTargetOutputName;
170 }
171
IsValidCopySubstitution(const Substitution * type)172 bool IsValidCopySubstitution(const Substitution* type) {
173 return IsValidToolSubstitution(type) || type == &SubstitutionSource;
174 }
175
IsValidCompileXCassetsSubstitution(const Substitution * type)176 bool IsValidCompileXCassetsSubstitution(const Substitution* type) {
177 return IsValidToolSubstitution(type) || type == &CSubstitutionLinkerInputs ||
178 type == &SubstitutionBundleProductType ||
179 type == &SubstitutionBundlePartialInfoPlist;
180 }
181
EnsureValidSubstitutions(const std::vector<const Substitution * > & types,bool (* is_valid_subst)(const Substitution *),const ParseNode * origin,Err * err)182 bool EnsureValidSubstitutions(const std::vector<const Substitution*>& types,
183 bool (*is_valid_subst)(const Substitution*),
184 const ParseNode* origin,
185 Err* err) {
186 for (const Substitution* type : types) {
187 if (!is_valid_subst(type)) {
188 *err = Err(origin, "Invalid substitution type.",
189 "The substitution " + std::string(type->name) +
190 " isn't valid for something\n"
191 "operating on a source file such as this.");
192 return false;
193 }
194 }
195 return true;
196 }
197