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