| 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 |