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 "tools/gn/substitution_type.h" 6 7#include <stdlib.h> 8 9#include "tools/gn/err.h" 10 11const char* kSubstitutionNames[SUBSTITUTION_NUM_TYPES] = { 12 "<<literal>>", // SUBSTITUTION_LITERAL 13 14 "{{source}}", // SUBSTITUTION_SOURCE 15 "{{output}}", // SUBSTITUTION_OUTPUT 16 17 "{{source_name_part}}", // SUBSTITUTION_NAME_PART 18 "{{source_file_part}}", // SUBSTITUTION_FILE_PART 19 "{{source_dir}}", // SUBSTITUTION_SOURCE_DIR 20 "{{source_root_relative_dir}}", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR 21 "{{source_gen_dir}}", // SUBSTITUTION_SOURCE_GEN_DIR 22 "{{source_out_dir}}", // SUBSTITUTION_SOURCE_OUT_DIR 23 24 "{{label}}", // SUBSTITUTION_LABEL 25 "{{root_gen_dir}}", // SUBSTITUTION_ROOT_GEN_DIR 26 "{{root_out_dir}}", // SUBSTITUTION_ROOT_OUT_DIR 27 "{{target_gen_dir}}", // SUBSTITUTION_TARGET_GEN_DIR 28 "{{target_out_dir}}", // SUBSTITUTION_TARGET_OUT_DIR 29 "{{target_output_name}}", // SUBSTITUTION_TARGET_OUTPUT_NAME 30 31 "{{cflags}}", // SUBSTITUTION_CFLAGS 32 "{{cflags_c}}", // SUBSTITUTION_CFLAGS_C 33 "{{cflags_cc}}", // SUBSTITUTION_CFLAGS_CC 34 "{{cflags_objc}}", // SUBSTITUTION_CFLAGS_OBJC 35 "{{cflags_objcc}}", // SUBSTITUTION_CFLAGS_OBJCC 36 "{{defines}}", // SUBSTITUTION_DEFINES 37 "{{include_dirs}}", // SUBSTITUTION_INCLUDE_DIRS 38 39 "{{inputs}}", // SUBSTITUTION_LINKER_INPUTS 40 "{{inputs_newline}}", // SUBSTITUTION_LINKER_INPUTS_NEWLINE 41 "{{ldflags}}", // SUBSTITUTION_LDFLAGS 42 "{{libs}}", // SUBSTITUTION_LIBS 43 "{{output_extension}}", // SUBSTITUTION_OUTPUT_EXTENSION 44 "{{solibs}}", // SUBSTITUTION_SOLIBS 45}; 46 47const char* kSubstitutionNinjaNames[SUBSTITUTION_NUM_TYPES] = { 48 NULL, // SUBSTITUTION_LITERAL 49 50 "in", // SUBSTITUTION_SOURCE 51 "out", // SUBSTITUTION_OUTPUT 52 53 "source_name_part", // SUBSTITUTION_NAME_PART 54 "source_file_part", // SUBSTITUTION_FILE_PART 55 "source_dir", // SUBSTITUTION_SOURCE_DIR 56 "source_root_relative_dir", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR 57 "source_gen_dir", // SUBSTITUTION_SOURCE_GEN_DIR 58 "source_out_dir", // SUBSTITUTION_SOURCE_OUT_DIR 59 60 "label", // SUBSTITUTION_LABEL 61 "root_gen_dir", // SUBSTITUTION_ROOT_GEN_DIR 62 "root_out_dir", // SUBSTITUTION_ROOT_OUT_DIR 63 "target_gen_dir", // SUBSTITUTION_TARGET_GEN_DIR 64 "target_out_dir", // SUBSTITUTION_TARGET_OUT_DIR 65 "target_output_name", // SUBSTITUTION_TARGET_OUTPUT_NAME 66 67 "cflags", // SUBSTITUTION_CFLAGS 68 "cflags_c", // SUBSTITUTION_CFLAGS_C 69 "cflags_cc", // SUBSTITUTION_CFLAGS_CC 70 "cflags_objc", // SUBSTITUTION_CFLAGS_OBJC 71 "cflags_objcc", // SUBSTITUTION_CFLAGS_OBJCC 72 "defines", // SUBSTITUTION_DEFINES 73 "include_dirs", // SUBSTITUTION_INCLUDE_DIRS 74 75 // LINKER_INPUTS expands to the same Ninja var as SUBSTITUTION_SOURCE. These 76 // are used in different contexts and are named differently to keep things 77 // clear, but they both expand to the "set of input files" for a build rule. 78 "in", // SUBSTITUTION_LINKER_INPUTS 79 "in_newline", // SUBSTITUTION_LINKER_INPUTS_NEWLINE 80 "ldflags", // SUBSTITUTION_LDFLAGS 81 "libs", // SUBSTITUTION_LIBS 82 "output_extension", // SUBSTITUTION_OUTPUT_EXTENSION 83 "solibs", // SUBSTITUTION_SOLIBS 84}; 85 86SubstitutionBits::SubstitutionBits() : used() { 87} 88 89void SubstitutionBits::MergeFrom(const SubstitutionBits& other) { 90 for (size_t i = 0; i < SUBSTITUTION_NUM_TYPES; i++) 91 used[i] |= other.used[i]; 92} 93 94void SubstitutionBits::FillVector(std::vector<SubstitutionType>* vect) const { 95 for (size_t i = SUBSTITUTION_FIRST_PATTERN; i < SUBSTITUTION_NUM_TYPES; i++) { 96 if (used[i]) 97 vect->push_back(static_cast<SubstitutionType>(i)); 98 } 99} 100 101bool SubstitutionIsInOutputDir(SubstitutionType type) { 102 return type == SUBSTITUTION_SOURCE_GEN_DIR || 103 type == SUBSTITUTION_SOURCE_OUT_DIR || 104 type == SUBSTITUTION_ROOT_GEN_DIR || 105 type == SUBSTITUTION_ROOT_OUT_DIR || 106 type == SUBSTITUTION_TARGET_GEN_DIR || 107 type == SUBSTITUTION_TARGET_OUT_DIR; 108} 109 110bool IsValidSourceSubstitution(SubstitutionType type) { 111 return type == SUBSTITUTION_LITERAL || 112 type == SUBSTITUTION_SOURCE || 113 type == SUBSTITUTION_SOURCE_NAME_PART || 114 type == SUBSTITUTION_SOURCE_FILE_PART || 115 type == SUBSTITUTION_SOURCE_DIR || 116 type == SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR || 117 type == SUBSTITUTION_SOURCE_GEN_DIR || 118 type == SUBSTITUTION_SOURCE_OUT_DIR; 119} 120 121bool IsValidToolSubstutition(SubstitutionType type) { 122 return type == SUBSTITUTION_LITERAL || 123 type == SUBSTITUTION_OUTPUT || 124 type == SUBSTITUTION_LABEL || 125 type == SUBSTITUTION_ROOT_GEN_DIR || 126 type == SUBSTITUTION_ROOT_OUT_DIR || 127 type == SUBSTITUTION_TARGET_GEN_DIR || 128 type == SUBSTITUTION_TARGET_OUT_DIR || 129 type == SUBSTITUTION_TARGET_OUTPUT_NAME; 130} 131 132bool IsValidCompilerSubstitution(SubstitutionType type) { 133 return IsValidToolSubstutition(type) || 134 IsValidSourceSubstitution(type) || 135 type == SUBSTITUTION_SOURCE || 136 type == SUBSTITUTION_CFLAGS || 137 type == SUBSTITUTION_CFLAGS_C || 138 type == SUBSTITUTION_CFLAGS_CC || 139 type == SUBSTITUTION_CFLAGS_OBJC || 140 type == SUBSTITUTION_CFLAGS_OBJCC || 141 type == SUBSTITUTION_DEFINES || 142 type == SUBSTITUTION_INCLUDE_DIRS; 143} 144 145bool IsValidCompilerOutputsSubstitution(SubstitutionType type) { 146 // All tool types except "output" (which would be infinitely recursive). 147 return (IsValidToolSubstutition(type) && type != SUBSTITUTION_OUTPUT) || 148 IsValidSourceSubstitution(type); 149} 150 151bool IsValidLinkerSubstitution(SubstitutionType type) { 152 return IsValidToolSubstutition(type) || 153 type == SUBSTITUTION_LINKER_INPUTS || 154 type == SUBSTITUTION_LINKER_INPUTS_NEWLINE || 155 type == SUBSTITUTION_LDFLAGS || 156 type == SUBSTITUTION_LIBS || 157 type == SUBSTITUTION_OUTPUT_EXTENSION || 158 type == SUBSTITUTION_SOLIBS; 159} 160 161bool IsValidLinkerOutputsSubstitution(SubstitutionType type) { 162 // All valid compiler outputs plus the output extension. 163 return IsValidCompilerOutputsSubstitution(type) || 164 type == SUBSTITUTION_OUTPUT_EXTENSION; 165} 166 167bool IsValidCopySubstitution(SubstitutionType type) { 168 return IsValidToolSubstutition(type) || 169 type == SUBSTITUTION_SOURCE; 170} 171 172bool EnsureValidSourcesSubstitutions( 173 const std::vector<SubstitutionType>& types, 174 const ParseNode* origin, 175 Err* err) { 176 for (size_t i = 0; i < types.size(); i++) { 177 if (!IsValidSourceSubstitution(types[i])) { 178 *err = Err(origin, "Invalid substitution type.", 179 "The substitution " + std::string(kSubstitutionNames[i]) + 180 " isn't valid for something\n" 181 "operating on a source file such as this."); 182 return false; 183 } 184 } 185 return true; 186} 187