| // Copyright 2014 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "tools/gn/substitution_type.h" | |
| #include <stddef.h> | |
| #include <stdlib.h> | |
| #include "tools/gn/err.h" | |
| const char* kSubstitutionNames[SUBSTITUTION_NUM_TYPES] = { | |
| "<<literal>>", // SUBSTITUTION_LITERAL | |
| "{{source}}", // SUBSTITUTION_SOURCE | |
| "{{output}}", // SUBSTITUTION_OUTPUT | |
| "{{source_name_part}}", // SUBSTITUTION_NAME_PART | |
| "{{source_file_part}}", // SUBSTITUTION_FILE_PART | |
| "{{source_dir}}", // SUBSTITUTION_SOURCE_DIR | |
| "{{source_root_relative_dir}}", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR | |
| "{{source_gen_dir}}", // SUBSTITUTION_SOURCE_GEN_DIR | |
| "{{source_out_dir}}", // SUBSTITUTION_SOURCE_OUT_DIR | |
| "{{source_target_relative}}", // SUBSTITUTION_SOURCE_TARGET_RELATIVE | |
| "{{label}}", // SUBSTITUTION_LABEL | |
| "{{label_name}}", // SUBSTITUTION_LABEL_NAME | |
| "{{root_gen_dir}}", // SUBSTITUTION_ROOT_GEN_DIR | |
| "{{root_out_dir}}", // SUBSTITUTION_ROOT_OUT_DIR | |
| "{{target_gen_dir}}", // SUBSTITUTION_TARGET_GEN_DIR | |
| "{{target_out_dir}}", // SUBSTITUTION_TARGET_OUT_DIR | |
| "{{target_output_name}}", // SUBSTITUTION_TARGET_OUTPUT_NAME | |
| "{{asmflags}}", // SUBSTITUTION_ASMFLAGS | |
| "{{cflags}}", // SUBSTITUTION_CFLAGS | |
| "{{cflags_c}}", // SUBSTITUTION_CFLAGS_C | |
| "{{cflags_cc}}", // SUBSTITUTION_CFLAGS_CC | |
| "{{cflags_objc}}", // SUBSTITUTION_CFLAGS_OBJC | |
| "{{cflags_objcc}}", // SUBSTITUTION_CFLAGS_OBJCC | |
| "{{defines}}", // SUBSTITUTION_DEFINES | |
| "{{include_dirs}}", // SUBSTITUTION_INCLUDE_DIRS | |
| "{{inputs}}", // SUBSTITUTION_LINKER_INPUTS | |
| "{{inputs_newline}}", // SUBSTITUTION_LINKER_INPUTS_NEWLINE | |
| "{{ldflags}}", // SUBSTITUTION_LDFLAGS | |
| "{{libs}}", // SUBSTITUTION_LIBS | |
| "{{output_dir}}", // SUBSTITUTION_OUTPUT_DIR | |
| "{{output_extension}}", // SUBSTITUTION_OUTPUT_EXTENSION | |
| "{{solibs}}", // SUBSTITUTION_SOLIBS | |
| "{{arflags}}", // SUBSTITUTION_ARFLAGS | |
| "{{bundle_root_dir}}", // SUBSTITUTION_BUNDLE_ROOT_DIR | |
| "{{bundle_contents_dir}}", // SUBSTITUTION_BUNDLE_CONTENTS_DIR | |
| "{{bundle_resources_dir}}", // SUBSTITUTION_BUNDLE_RESOURCES_DIR | |
| "{{bundle_executable_dir}}", // SUBSTITUTION_BUNDLE_EXECUTABLE_DIR | |
| "{{bundle_plugins_dir}}", // SUBSTITUTION_BUNDLE_PLUGINS_DIR | |
| "{{bundle_product_type}}", // SUBSTITUTION_BUNDLE_PRODUCT_TYPE | |
| "{{bundle_partial_info_plist}}", // SUBSTITUTION_BUNDLE_PARTIAL_INFO_PLIST, | |
| "{{response_file_name}}", // SUBSTITUTION_RSP_FILE_NAME | |
| }; | |
| const char* kSubstitutionNinjaNames[SUBSTITUTION_NUM_TYPES] = { | |
| nullptr, // SUBSTITUTION_LITERAL | |
| "in", // SUBSTITUTION_SOURCE | |
| "out", // SUBSTITUTION_OUTPUT | |
| "source_name_part", // SUBSTITUTION_NAME_PART | |
| "source_file_part", // SUBSTITUTION_FILE_PART | |
| "source_dir", // SUBSTITUTION_SOURCE_DIR | |
| "source_root_relative_dir", // SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR | |
| "source_gen_dir", // SUBSTITUTION_SOURCE_GEN_DIR | |
| "source_out_dir", // SUBSTITUTION_SOURCE_OUT_DIR | |
| "source_target_relative", // SUBSTITUTION_SOURCE_TARGET_RELATIVE | |
| "label", // SUBSTITUTION_LABEL | |
| "label_name", // SUBSTITUTION_LABEL_NAME | |
| "root_gen_dir", // SUBSTITUTION_ROOT_GEN_DIR | |
| "root_out_dir", // SUBSTITUTION_ROOT_OUT_DIR | |
| "target_gen_dir", // SUBSTITUTION_TARGET_GEN_DIR | |
| "target_out_dir", // SUBSTITUTION_TARGET_OUT_DIR | |
| "target_output_name", // SUBSTITUTION_TARGET_OUTPUT_NAME | |
| "asmflags", // SUBSTITUTION_ASMFLAGS | |
| "cflags", // SUBSTITUTION_CFLAGS | |
| "cflags_c", // SUBSTITUTION_CFLAGS_C | |
| "cflags_cc", // SUBSTITUTION_CFLAGS_CC | |
| "cflags_objc", // SUBSTITUTION_CFLAGS_OBJC | |
| "cflags_objcc", // SUBSTITUTION_CFLAGS_OBJCC | |
| "defines", // SUBSTITUTION_DEFINES | |
| "include_dirs", // SUBSTITUTION_INCLUDE_DIRS | |
| // LINKER_INPUTS expands to the same Ninja var as SUBSTITUTION_SOURCE. These | |
| // are used in different contexts and are named differently to keep things | |
| // clear, but they both expand to the "set of input files" for a build rule. | |
| "in", // SUBSTITUTION_LINKER_INPUTS | |
| "in_newline", // SUBSTITUTION_LINKER_INPUTS_NEWLINE | |
| "ldflags", // SUBSTITUTION_LDFLAGS | |
| "libs", // SUBSTITUTION_LIBS | |
| "output_dir", // SUBSTITUTION_OUTPUT_DIR | |
| "output_extension", // SUBSTITUTION_OUTPUT_EXTENSION | |
| "solibs", // SUBSTITUTION_SOLIBS | |
| "arflags", // SUBSTITUTION_ARFLAGS | |
| "bundle_root_dir", // SUBSTITUTION_BUNDLE_ROOT_DIR | |
| "bundle_contents_dir", // SUBSTITUTION_BUNDLE_CONTENTS_DIR | |
| "bundle_resources_dir", // SUBSTITUTION_BUNDLE_RESOURCES_DIR | |
| "bundle_executable_dir", // SUBSTITUTION_BUNDLE_EXECUTABLE_DIR | |
| "bundle_plugins_dir", // SUBSTITUTION_BUNDLE_PLUGINS_DIR | |
| "product_type", // SUBSTITUTION_BUNDLE_PRODUCT_TYPE | |
| "partial_info_plist", // SUBSTITUTION_BUNDLE_PARTIAL_INFO_PLIST | |
| "rspfile", // SUBSTITUTION_RSP_FILE_NAME | |
| }; | |
| SubstitutionBits::SubstitutionBits() : used() {} | |
| void SubstitutionBits::MergeFrom(const SubstitutionBits& other) { | |
| for (size_t i = 0; i < SUBSTITUTION_NUM_TYPES; i++) | |
| used[i] |= other.used[i]; | |
| } | |
| void SubstitutionBits::FillVector(std::vector<SubstitutionType>* vect) const { | |
| for (size_t i = SUBSTITUTION_FIRST_PATTERN; i < SUBSTITUTION_NUM_TYPES; i++) { | |
| if (used[i]) | |
| vect->push_back(static_cast<SubstitutionType>(i)); | |
| } | |
| } | |
| bool SubstitutionIsInOutputDir(SubstitutionType type) { | |
| return type == SUBSTITUTION_SOURCE_GEN_DIR || | |
| type == SUBSTITUTION_SOURCE_OUT_DIR || | |
| type == SUBSTITUTION_ROOT_GEN_DIR || | |
| type == SUBSTITUTION_ROOT_OUT_DIR || | |
| type == SUBSTITUTION_TARGET_GEN_DIR || | |
| type == SUBSTITUTION_TARGET_OUT_DIR; | |
| } | |
| bool SubstitutionIsInBundleDir(SubstitutionType type) { | |
| return type == SUBSTITUTION_BUNDLE_ROOT_DIR || | |
| type == SUBSTITUTION_BUNDLE_CONTENTS_DIR || | |
| type == SUBSTITUTION_BUNDLE_RESOURCES_DIR || | |
| type == SUBSTITUTION_BUNDLE_EXECUTABLE_DIR || | |
| type == SUBSTITUTION_BUNDLE_PLUGINS_DIR; | |
| } | |
| bool IsValidBundleDataSubstitution(SubstitutionType type) { | |
| return type == SUBSTITUTION_LITERAL || | |
| type == SUBSTITUTION_SOURCE_NAME_PART || | |
| type == SUBSTITUTION_SOURCE_FILE_PART || | |
| type == SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR || | |
| type == SUBSTITUTION_BUNDLE_ROOT_DIR || | |
| type == SUBSTITUTION_BUNDLE_CONTENTS_DIR || | |
| type == SUBSTITUTION_BUNDLE_RESOURCES_DIR || | |
| type == SUBSTITUTION_BUNDLE_EXECUTABLE_DIR || | |
| type == SUBSTITUTION_BUNDLE_PLUGINS_DIR; | |
| } | |
| bool IsValidSourceSubstitution(SubstitutionType type) { | |
| return type == SUBSTITUTION_LITERAL || type == SUBSTITUTION_SOURCE || | |
| type == SUBSTITUTION_SOURCE_NAME_PART || | |
| type == SUBSTITUTION_SOURCE_FILE_PART || | |
| type == SUBSTITUTION_SOURCE_DIR || | |
| type == SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR || | |
| type == SUBSTITUTION_SOURCE_GEN_DIR || | |
| type == SUBSTITUTION_SOURCE_OUT_DIR || | |
| type == SUBSTITUTION_SOURCE_TARGET_RELATIVE; | |
| } | |
| bool IsValidScriptArgsSubstitution(SubstitutionType type) { | |
| return IsValidSourceSubstitution(type) || type == SUBSTITUTION_RSP_FILE_NAME; | |
| } | |
| bool IsValidToolSubstitution(SubstitutionType type) { | |
| return type == SUBSTITUTION_LITERAL || type == SUBSTITUTION_OUTPUT || | |
| type == SUBSTITUTION_LABEL || type == SUBSTITUTION_LABEL_NAME || | |
| type == SUBSTITUTION_ROOT_GEN_DIR || | |
| type == SUBSTITUTION_ROOT_OUT_DIR || | |
| type == SUBSTITUTION_TARGET_GEN_DIR || | |
| type == SUBSTITUTION_TARGET_OUT_DIR || | |
| type == SUBSTITUTION_TARGET_OUTPUT_NAME; | |
| } | |
| bool IsValidCompilerSubstitution(SubstitutionType type) { | |
| return IsValidToolSubstitution(type) || IsValidSourceSubstitution(type) || | |
| type == SUBSTITUTION_SOURCE || type == SUBSTITUTION_ASMFLAGS || | |
| type == SUBSTITUTION_CFLAGS || type == SUBSTITUTION_CFLAGS_C || | |
| type == SUBSTITUTION_CFLAGS_CC || type == SUBSTITUTION_CFLAGS_OBJC || | |
| type == SUBSTITUTION_CFLAGS_OBJCC || type == SUBSTITUTION_DEFINES || | |
| type == SUBSTITUTION_INCLUDE_DIRS; | |
| } | |
| bool IsValidCompilerOutputsSubstitution(SubstitutionType type) { | |
| // All tool types except "output" (which would be infinitely recursive). | |
| return (IsValidToolSubstitution(type) && type != SUBSTITUTION_OUTPUT) || | |
| IsValidSourceSubstitution(type); | |
| } | |
| bool IsValidLinkerSubstitution(SubstitutionType type) { | |
| return IsValidToolSubstitution(type) || type == SUBSTITUTION_LINKER_INPUTS || | |
| type == SUBSTITUTION_LINKER_INPUTS_NEWLINE || | |
| type == SUBSTITUTION_LDFLAGS || type == SUBSTITUTION_LIBS || | |
| type == SUBSTITUTION_OUTPUT_DIR || | |
| type == SUBSTITUTION_OUTPUT_EXTENSION || type == SUBSTITUTION_SOLIBS; | |
| } | |
| bool IsValidLinkerOutputsSubstitution(SubstitutionType type) { | |
| // All valid compiler outputs plus the output extension. | |
| return IsValidCompilerOutputsSubstitution(type) || | |
| type == SUBSTITUTION_OUTPUT_DIR || | |
| type == SUBSTITUTION_OUTPUT_EXTENSION; | |
| } | |
| bool IsValidALinkSubstitution(SubstitutionType type) { | |
| return IsValidToolSubstitution(type) || type == SUBSTITUTION_LINKER_INPUTS || | |
| type == SUBSTITUTION_LINKER_INPUTS_NEWLINE || | |
| type == SUBSTITUTION_ARFLAGS || type == SUBSTITUTION_OUTPUT_DIR || | |
| type == SUBSTITUTION_OUTPUT_EXTENSION; | |
| } | |
| bool IsValidCopySubstitution(SubstitutionType type) { | |
| return IsValidToolSubstitution(type) || type == SUBSTITUTION_SOURCE; | |
| } | |
| bool IsValidCompileXCassetsSubstitution(SubstitutionType type) { | |
| return IsValidToolSubstitution(type) || type == SUBSTITUTION_LINKER_INPUTS || | |
| type == SUBSTITUTION_BUNDLE_PRODUCT_TYPE || | |
| type == SUBSTITUTION_BUNDLE_PARTIAL_INFO_PLIST; | |
| } | |
| bool EnsureValidSubstitutions(const std::vector<SubstitutionType>& types, | |
| bool (*is_valid_subst)(SubstitutionType), | |
| const ParseNode* origin, | |
| Err* err) { | |
| for (SubstitutionType type : types) { | |
| if (!is_valid_subst(type)) { | |
| *err = Err(origin, "Invalid substitution type.", | |
| "The substitution " + std::string(kSubstitutionNames[type]) + | |
| " isn't valid for something\n" | |
| "operating on a source file such as this."); | |
| return false; | |
| } | |
| } | |
| return true; | |
| } |