OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef TOOLS_GN_FILE_TEMPLATE_H_ | 5 #ifndef TOOLS_GN_FILE_TEMPLATE_H_ |
6 #define TOOLS_GN_FILE_TEMPLATE_H_ | 6 #define TOOLS_GN_FILE_TEMPLATE_H_ |
7 | 7 |
8 #include <iosfwd> | 8 #include <iosfwd> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/containers/stack_container.h" | 11 #include "base/containers/stack_container.h" |
12 #include "tools/gn/err.h" | 12 #include "tools/gn/err.h" |
13 #include "tools/gn/value.h" | 13 #include "tools/gn/value.h" |
14 | 14 |
15 struct EscapeOptions; | 15 struct EscapeOptions; |
16 class ParseNode; | 16 class ParseNode; |
| 17 class Settings; |
17 class SourceFile; | 18 class SourceFile; |
18 class Target; | 19 class Target; |
19 | 20 |
20 extern const char kSourceExpansion_Help[]; | 21 extern const char kSourceExpansion_Help[]; |
21 | 22 |
22 // A FileTemplate object implements source expansion for a given "template" | 23 // A FileTemplate object implements source expansion for a given "template" |
23 // (either outputs or args, depending on the target type). | 24 // (either outputs or args, depending on the target type). |
24 // | 25 // |
25 // There are two ways you can use this. You can make a template and then | 26 // There are two ways you can use this. You can make a template and then |
26 // apply a source to it to get a list of outputs manually. Or you can do the | 27 // apply a source to it to get a list of outputs manually. Or you can do the |
27 // actual substitution in Ninja, writing the arguments in a rule and using | 28 // actual substitution in Ninja, writing the arguments in a rule and using |
28 // variables in build statements to invoke the rule with the right | 29 // variables in build statements to invoke the rule with the right |
29 // substitutions. | 30 // substitutions. |
30 class FileTemplate { | 31 class FileTemplate { |
31 public: | 32 public: |
32 struct Subrange { | 33 struct Subrange { |
| 34 // See the help in the .cc file for what these mean. |
33 enum Type { | 35 enum Type { |
34 LITERAL = 0, | 36 LITERAL = 0, |
35 | 37 |
36 // {{source}} -> expands to be the source file name relative to the build | 38 SOURCE, // {{source}} |
37 // root dir. | 39 NAME_PART, // {{source_name_part}} |
38 SOURCE, | 40 FILE_PART, // {{source_file_part}} |
39 | 41 SOURCE_DIR, // {{source_dir}} |
40 // {{source_name_part}} -> file name without extension or directory. | 42 ROOT_RELATIVE_DIR, // {{root_relative_dir}} |
41 // Maps "foo/bar.txt" to "bar". | 43 SOURCE_GEN_DIR, // {{source_gen_dir}} |
42 NAME_PART, | 44 SOURCE_OUT_DIR, // {{source_out_dir}} |
43 | |
44 // {{source_file_part}} -> file name including extension but no directory. | |
45 // Maps "foo/bar.txt" to "bar.txt". | |
46 FILE_PART, | |
47 | 45 |
48 NUM_TYPES // Must be last | 46 NUM_TYPES // Must be last |
49 }; | 47 }; |
50 Subrange(Type t, const std::string& l = std::string()) | 48 Subrange(Type t, const std::string& l = std::string()) |
51 : type(t), | 49 : type(t), |
52 literal(l) { | 50 literal(l) { |
53 } | 51 } |
54 | 52 |
55 Type type; | 53 Type type; |
56 | 54 |
57 // When type_ == LITERAL, this specifies the literal. | 55 // When type_ == LITERAL, this specifies the literal. |
58 std::string literal; | 56 std::string literal; |
59 }; | 57 }; |
60 | 58 |
61 // Constructs a template from the given value. On error, the err will be | 59 // Constructs a template from the given value. On error, the err will be |
62 // set. In this case you should not use this object. | 60 // set. In this case you should not use this object. |
63 FileTemplate(const Value& t, Err* err); | 61 FileTemplate(const Settings* settings, const Value& t, Err* err); |
64 FileTemplate(const std::vector<std::string>& t); | 62 FileTemplate(const Settings* settings, const std::vector<std::string>& t); |
65 FileTemplate(const std::vector<SourceFile>& t); | 63 FileTemplate(const Settings* settings, const std::vector<SourceFile>& t); |
66 | 64 |
67 ~FileTemplate(); | 65 ~FileTemplate(); |
68 | 66 |
69 // Returns an output template representing the given target's script | 67 // Returns an output template representing the given target's script |
70 // outputs. | 68 // outputs. |
71 static FileTemplate GetForTargetOutputs(const Target* target); | 69 static FileTemplate GetForTargetOutputs(const Target* target); |
72 | 70 |
73 // Returns true if the given substitution type is used by this template. | 71 // Returns true if the given substitution type is used by this template. |
74 bool IsTypeUsed(Subrange::Type type) const; | 72 bool IsTypeUsed(Subrange::Type type) const; |
75 | 73 |
76 // Returns true if there are any substitutions. | 74 // Returns true if there are any substitutions. |
77 bool has_substitutions() const { return has_substitutions_; } | 75 bool has_substitutions() const { return has_substitutions_; } |
78 | 76 |
79 // Applies this template to the given list of sources, appending all | 77 // Applies the template to one source file. The results will be *appended* to |
80 // results to the given dest list. The sources must be a list for the | 78 // the output. |
81 // one that takes a value as an input, otherwise the given error will be set. | 79 void Apply(const SourceFile& source, |
82 void Apply(const Value& sources, | 80 std::vector<std::string>* output) const; |
83 const ParseNode* origin, | |
84 std::vector<Value>* dest, | |
85 Err* err) const; | |
86 | |
87 // Low-level version of Apply that handles one source file. The results | |
88 // will be *appended* to the output. | |
89 void ApplyString(const std::string& input, | |
90 std::vector<std::string>* output) const; | |
91 | 81 |
92 // Writes a string representing the template with Ninja variables for the | 82 // Writes a string representing the template with Ninja variables for the |
93 // substitutions, and the literals escaped for Ninja consumption. | 83 // substitutions, and the literals escaped for Ninja consumption. |
94 // | 84 // |
95 // For example, if the input is "foo{{source_name_part}}bar" this will write | 85 // For example, if the input is "foo{{source_name_part}}bar" this will write |
96 // foo${source_name_part}bar. If there are multiple templates (we were | 86 // foo${source_name_part}bar. If there are multiple templates (we were |
97 // constucted with a list of more than one item) then the values will be | 87 // constucted with a list of more than one item) then the values will be |
98 // separated by spaces. | 88 // separated by spaces. |
99 // | 89 // |
100 // If this template is nonempty, we will first print out a space to separate | 90 // If this template is nonempty, we will first print out a space to separate |
101 // it from the previous command. | 91 // it from the previous command. |
102 // | 92 // |
103 // The names used for the Ninja variables will be the same ones used by | 93 // The names used for the Ninja variables will be the same ones used by |
104 // WriteNinjaVariablesForSubstitution. You would use this to define the Ninja | 94 // WriteNinjaVariablesForSubstitution. You would use this to define the Ninja |
105 // rule, and then define the variables to substitute for each file using | 95 // rule, and then define the variables to substitute for each file using |
106 // WriteNinjaVariablesForSubstitution. | 96 // WriteNinjaVariablesForSubstitution. |
107 void WriteWithNinjaExpansions(std::ostream& out) const; | 97 void WriteWithNinjaExpansions(std::ostream& out) const; |
108 | 98 |
109 // Writes to the given stream the variable declarations for extracting the | 99 // Writes to the given stream the variable declarations for extracting the |
110 // required parts of the given source file string. The results will be | 100 // required parts of the given source file string. The results will be |
111 // indented two spaces. | 101 // indented two spaces. |
112 // | 102 // |
113 // This is used to set up a build statement to invoke a rule where the rule | 103 // This is used to set up a build statement to invoke a rule where the rule |
114 // contains a representation of this file template to be expanded by Ninja | 104 // contains a representation of this file template to be expanded by Ninja |
115 // (see GetWithNinjaExpansions). | 105 // (see GetWithNinjaExpansions). |
116 void WriteNinjaVariablesForSubstitution( | 106 void WriteNinjaVariablesForSubstitution( |
117 std::ostream& out, | 107 std::ostream& out, |
118 const std::string& source, | 108 const Settings* settings, |
| 109 const SourceFile& source, |
119 const EscapeOptions& escape_options) const; | 110 const EscapeOptions& escape_options) const; |
120 | 111 |
121 // Returns the Ninja variable name used by the above Ninja functions to | 112 // Returns the Ninja variable name used by the above Ninja functions to |
122 // substitute for the given type. | 113 // substitute for the given type. |
123 static const char* GetNinjaVariableNameForType(Subrange::Type type); | 114 static const char* GetNinjaVariableNameForType(Subrange::Type type); |
124 | 115 |
125 // Extracts the given type of substitution from the given source. The source | 116 // Extracts the given type of substitution from the given source. The source |
126 // should be the file name relative to the output directory. | 117 // should be the file name relative to the output directory. |
127 static std::string GetSubstitution(const std::string& source, | 118 static std::string GetSubstitution(const Settings* settings, |
| 119 const SourceFile& source, |
128 Subrange::Type type); | 120 Subrange::Type type); |
129 | 121 |
130 // Known template types, these include the "{{ }}" | 122 // Known template types, these include the "{{ }}" |
131 static const char kSource[]; | 123 static const char kSource[]; |
132 static const char kSourceNamePart[]; | 124 static const char kSourceNamePart[]; |
133 static const char kSourceFilePart[]; | 125 static const char kSourceFilePart[]; |
| 126 static const char kSourceDir[]; |
| 127 static const char kRootRelDir[]; |
| 128 static const char kSourceGenDir[]; |
| 129 static const char kSourceOutDir[]; |
134 | 130 |
135 private: | 131 private: |
136 typedef base::StackVector<Subrange, 8> Template; | 132 typedef base::StackVector<Subrange, 8> Template; |
137 typedef base::StackVector<Template, 8> TemplateVector; | 133 typedef base::StackVector<Template, 8> TemplateVector; |
138 | 134 |
139 void ParseInput(const Value& value, Err* err); | 135 void ParseInput(const Value& value, Err* err); |
140 | 136 |
141 // Parses a template string and adds it to the templates_ list. | 137 // Parses a template string and adds it to the templates_ list. |
142 void ParseOneTemplateString(const std::string& str); | 138 void ParseOneTemplateString(const std::string& str); |
143 | 139 |
| 140 const Settings* settings_; |
| 141 |
144 TemplateVector templates_; | 142 TemplateVector templates_; |
145 | 143 |
146 // The corresponding value is set to true if the given subrange type is | 144 // The corresponding value is set to true if the given subrange type is |
147 // required. This allows us to precompute these types whem applying them | 145 // required. This allows us to precompute these types whem applying them |
148 // to a given source file. | 146 // to a given source file. |
149 bool types_required_[Subrange::NUM_TYPES]; | 147 bool types_required_[Subrange::NUM_TYPES]; |
150 | 148 |
151 // Set when any of the types_required_ is true. Otherwise, everythins is a | 149 // Set when any of the types_required_ is true. Otherwise, everythins is a |
152 // literal (a common case so we can optimize some code paths). | 150 // literal (a common case so we can optimize some code paths). |
153 bool has_substitutions_; | 151 bool has_substitutions_; |
154 }; | 152 }; |
155 | 153 |
156 #endif // TOOLS_GN_FILE_TEMPLATE_H_ | 154 #endif // TOOLS_GN_FILE_TEMPLATE_H_ |
OLD | NEW |