blob: 14bdcdc8dfc3b642cd2f814994c61307f03f9e13 [file] [log] [blame]
// 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;
}