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