|  | // Copyright (c) 2013 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. | 
|  |  | 
|  | #ifndef TOOLS_GN_FUNCTIONS_H_ | 
|  | #define TOOLS_GN_FUNCTIONS_H_ | 
|  |  | 
|  | #include <map> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/strings/string_piece.h" | 
|  |  | 
|  | class Err; | 
|  | class BlockNode; | 
|  | class FunctionCallNode; | 
|  | class Label; | 
|  | class ListNode; | 
|  | class ParseNode; | 
|  | class Scope; | 
|  | class Value; | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | namespace functions { | 
|  |  | 
|  | // This type of function invocation has no block and evaluates its arguments | 
|  | // itself rather than taking a pre-executed list. This allows us to implement | 
|  | // certain built-in functions. | 
|  | typedef Value (*SelfEvaluatingArgsFunction)(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | Err* err); | 
|  |  | 
|  | // This type of function invocation takes a block node that it will execute. | 
|  | typedef Value (*GenericBlockFunction)(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | // This type of function takes a block, but does not need to control execution | 
|  | // of it. The dispatch function will pre-execute the block and pass the | 
|  | // resulting block_scope to the function. | 
|  | typedef Value (*ExecutedBlockFunction)(const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Scope* block_scope, | 
|  | Err* err); | 
|  |  | 
|  | // This type of function does not take a block. It just has arguments. | 
|  | typedef Value (*NoBlockFunction)(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kAction[]; | 
|  | extern const char kAction_HelpShort[]; | 
|  | extern const char kAction_Help[]; | 
|  | Value RunAction(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kActionForEach[]; | 
|  | extern const char kActionForEach_HelpShort[]; | 
|  | extern const char kActionForEach_Help[]; | 
|  | Value RunActionForEach(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kAssert[]; | 
|  | extern const char kAssert_HelpShort[]; | 
|  | extern const char kAssert_Help[]; | 
|  | Value RunAssert(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kBundleData[]; | 
|  | extern const char kBundleData_HelpShort[]; | 
|  | extern const char kBundleData_Help[]; | 
|  | Value RunBundleData(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kCreateBundle[]; | 
|  | extern const char kCreateBundle_HelpShort[]; | 
|  | extern const char kCreateBundle_Help[]; | 
|  | Value RunCreateBundle(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kConfig[]; | 
|  | extern const char kConfig_HelpShort[]; | 
|  | extern const char kConfig_Help[]; | 
|  | Value RunConfig(const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Scope* block_scope, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kCopy[]; | 
|  | extern const char kCopy_HelpShort[]; | 
|  | extern const char kCopy_Help[]; | 
|  | Value RunCopy(const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Scope* block_scope, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kDeclareArgs[]; | 
|  | extern const char kDeclareArgs_HelpShort[]; | 
|  | extern const char kDeclareArgs_Help[]; | 
|  | Value RunDeclareArgs(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kDefined[]; | 
|  | extern const char kDefined_HelpShort[]; | 
|  | extern const char kDefined_Help[]; | 
|  | Value RunDefined(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kExecScript[]; | 
|  | extern const char kExecScript_HelpShort[]; | 
|  | extern const char kExecScript_Help[]; | 
|  | Value RunExecScript(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kExecutable[]; | 
|  | extern const char kExecutable_HelpShort[]; | 
|  | extern const char kExecutable_Help[]; | 
|  | Value RunExecutable(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kForEach[]; | 
|  | extern const char kForEach_HelpShort[]; | 
|  | extern const char kForEach_Help[]; | 
|  | Value RunForEach(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kForwardVariablesFrom[]; | 
|  | extern const char kForwardVariablesFrom_HelpShort[]; | 
|  | extern const char kForwardVariablesFrom_Help[]; | 
|  | Value RunForwardVariablesFrom(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kGetEnv[]; | 
|  | extern const char kGetEnv_HelpShort[]; | 
|  | extern const char kGetEnv_Help[]; | 
|  | Value RunGetEnv(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kGetLabelInfo[]; | 
|  | extern const char kGetLabelInfo_HelpShort[]; | 
|  | extern const char kGetLabelInfo_Help[]; | 
|  | Value RunGetLabelInfo(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kGetPathInfo[]; | 
|  | extern const char kGetPathInfo_HelpShort[]; | 
|  | extern const char kGetPathInfo_Help[]; | 
|  | Value RunGetPathInfo(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kGetTargetOutputs[]; | 
|  | extern const char kGetTargetOutputs_HelpShort[]; | 
|  | extern const char kGetTargetOutputs_Help[]; | 
|  | Value RunGetTargetOutputs(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kGroup[]; | 
|  | extern const char kGroup_HelpShort[]; | 
|  | extern const char kGroup_Help[]; | 
|  | Value RunGroup(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kImport[]; | 
|  | extern const char kImport_HelpShort[]; | 
|  | extern const char kImport_Help[]; | 
|  | Value RunImport(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kLoadableModule[]; | 
|  | extern const char kLoadableModule_HelpShort[]; | 
|  | extern const char kLoadableModule_Help[]; | 
|  | Value RunLoadableModule(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kNotNeeded[]; | 
|  | extern const char kNotNeeded_HelpShort[]; | 
|  | extern const char kNotNeeded_Help[]; | 
|  | Value RunNotNeeded(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kPool[]; | 
|  | extern const char kPool_HelpShort[]; | 
|  | extern const char kPool_Help[]; | 
|  | Value RunPool(const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Scope* block_scope, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kPrint[]; | 
|  | extern const char kPrint_HelpShort[]; | 
|  | extern const char kPrint_Help[]; | 
|  | Value RunPrint(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kProcessFileTemplate[]; | 
|  | extern const char kProcessFileTemplate_HelpShort[]; | 
|  | extern const char kProcessFileTemplate_Help[]; | 
|  | Value RunProcessFileTemplate(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kReadFile[]; | 
|  | extern const char kReadFile_HelpShort[]; | 
|  | extern const char kReadFile_Help[]; | 
|  | Value RunReadFile(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kRebasePath[]; | 
|  | extern const char kRebasePath_HelpShort[]; | 
|  | extern const char kRebasePath_Help[]; | 
|  | Value RunRebasePath(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kSetDefaults[]; | 
|  | extern const char kSetDefaults_HelpShort[]; | 
|  | extern const char kSetDefaults_Help[]; | 
|  | Value RunSetDefaults(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kSetDefaultToolchain[]; | 
|  | extern const char kSetDefaultToolchain_HelpShort[]; | 
|  | extern const char kSetDefaultToolchain_Help[]; | 
|  | Value RunSetDefaultToolchain(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kSetSourcesAssignmentFilter[]; | 
|  | extern const char kSetSourcesAssignmentFilter_HelpShort[]; | 
|  | extern const char kSetSourcesAssignmentFilter_Help[]; | 
|  | Value RunSetSourcesAssignmentFilter(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kSharedLibrary[]; | 
|  | extern const char kSharedLibrary_HelpShort[]; | 
|  | extern const char kSharedLibrary_Help[]; | 
|  | Value RunSharedLibrary(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kSourceSet[]; | 
|  | extern const char kSourceSet_HelpShort[]; | 
|  | extern const char kSourceSet_Help[]; | 
|  | Value RunSourceSet(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kSplitList[]; | 
|  | extern const char kSplitList_HelpShort[]; | 
|  | extern const char kSplitList_Help[]; | 
|  | Value RunSplitList(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kStaticLibrary[]; | 
|  | extern const char kStaticLibrary_HelpShort[]; | 
|  | extern const char kStaticLibrary_Help[]; | 
|  | Value RunStaticLibrary(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kTarget[]; | 
|  | extern const char kTarget_HelpShort[]; | 
|  | extern const char kTarget_Help[]; | 
|  | Value RunTarget(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kTemplate[]; | 
|  | extern const char kTemplate_HelpShort[]; | 
|  | extern const char kTemplate_Help[]; | 
|  | Value RunTemplate(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kTool[]; | 
|  | extern const char kTool_HelpShort[]; | 
|  | extern const char kTool_Help[]; | 
|  | Value RunTool(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kToolchain[]; | 
|  | extern const char kToolchain_HelpShort[]; | 
|  | extern const char kToolchain_Help[]; | 
|  | Value RunToolchain(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | BlockNode* block, | 
|  | Err* err); | 
|  |  | 
|  | extern const char kWriteFile[]; | 
|  | extern const char kWriteFile_HelpShort[]; | 
|  | extern const char kWriteFile_Help[]; | 
|  | Value RunWriteFile(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | // One function record. Only one of the given runner types will be non-null | 
|  | // which indicates the type of function it is. | 
|  | struct FunctionInfo { | 
|  | FunctionInfo(); | 
|  | FunctionInfo(SelfEvaluatingArgsFunction seaf, | 
|  | const char* in_help_short, | 
|  | const char* in_help, | 
|  | bool in_is_target); | 
|  | FunctionInfo(GenericBlockFunction gbf, | 
|  | const char* in_help_short, | 
|  | const char* in_help, | 
|  | bool in_is_target); | 
|  | FunctionInfo(ExecutedBlockFunction ebf, | 
|  | const char* in_help_short, | 
|  | const char* in_help, | 
|  | bool in_is_target); | 
|  | FunctionInfo(NoBlockFunction nbf, | 
|  | const char* in_help_short, | 
|  | const char* in_help, | 
|  | bool in_is_target); | 
|  |  | 
|  | SelfEvaluatingArgsFunction self_evaluating_args_runner; | 
|  | GenericBlockFunction generic_block_runner; | 
|  | ExecutedBlockFunction executed_block_runner; | 
|  | NoBlockFunction no_block_runner; | 
|  |  | 
|  | const char* help_short; | 
|  | const char* help; | 
|  |  | 
|  | bool is_target; | 
|  | }; | 
|  |  | 
|  | typedef std::map<base::StringPiece, FunctionInfo> FunctionInfoMap; | 
|  |  | 
|  | // Returns the mapping of all built-in functions. | 
|  | const FunctionInfoMap& GetFunctions(); | 
|  |  | 
|  | // Runs the given function. | 
|  | Value RunFunction(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const ListNode* args_list, | 
|  | BlockNode* block,  // Optional. | 
|  | Err* err); | 
|  |  | 
|  | }  // namespace functions | 
|  |  | 
|  | // Helper functions ----------------------------------------------------------- | 
|  |  | 
|  | // Validates that the scope that a value is defined in is not the scope | 
|  | // of the current declare_args() call, if that's what we're in. It is | 
|  | // illegal to read a value from inside the same declare_args() call, since | 
|  | // the overrides will not have been applied yet (see `gn help declare_args` | 
|  | // for more). | 
|  | bool EnsureNotReadingFromSameDeclareArgs(const ParseNode* node, | 
|  | const Scope* cur_scope, | 
|  | const Scope* val_scope, | 
|  | Err* err); | 
|  |  | 
|  | // Verifies that the current scope is not processing an import. If it is, it | 
|  | // will set the error, blame the given parse node for it, and return false. | 
|  | bool EnsureNotProcessingImport(const ParseNode* node, | 
|  | const Scope* scope, | 
|  | Err* err); | 
|  |  | 
|  | // Like EnsureNotProcessingImport but checks for running the build config. | 
|  | bool EnsureNotProcessingBuildConfig(const ParseNode* node, | 
|  | const Scope* scope, | 
|  | Err* err); | 
|  |  | 
|  | // Sets up the |block_scope| for executing a target (or something like it). | 
|  | // The |scope| is the containing scope. It should have been already set as the | 
|  | // parent for the |block_scope| when the |block_scope| was created. | 
|  | // | 
|  | // This will set up the target defaults and set the |target_name| variable in | 
|  | // the block scope to the current target name, which is assumed to be the first | 
|  | // argument to the function. | 
|  | // | 
|  | // On success, returns true. On failure, sets the error and returns false. | 
|  | bool FillTargetBlockScope(const Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::string& target_type, | 
|  | const BlockNode* block, | 
|  | const std::vector<Value>& args, | 
|  | Scope* block_scope, | 
|  | Err* err); | 
|  |  | 
|  | // Sets the given error to a message explaining that the function call requires | 
|  | // a block. | 
|  | void FillNeedsBlockError(const FunctionCallNode* function, Err* err); | 
|  |  | 
|  | // Validates that the given function call has one string argument. This is | 
|  | // the most common function signature, so it saves space to have this helper. | 
|  | // Returns false and sets the error on failure. | 
|  | bool EnsureSingleStringArg(const FunctionCallNode* function, | 
|  | const std::vector<Value>& args, | 
|  | Err* err); | 
|  |  | 
|  | // Returns the name of the toolchain for the given scope. | 
|  | const Label& ToolchainLabelForScope(const Scope* scope); | 
|  |  | 
|  | // Generates a label for the given scope, using the current directory and | 
|  | // toolchain, and the given name. | 
|  | Label MakeLabelForScope(const Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const std::string& name); | 
|  |  | 
|  | // Some types of blocks can't be nested inside other ones. For such cases, | 
|  | // instantiate this object upon entering the block and Enter() will fail if | 
|  | // there is already another non-nestable block on the stack. | 
|  | class NonNestableBlock { | 
|  | public: | 
|  | // type_description is a string that will be used in error messages | 
|  | // describing the type of the block, for example, "template" or "config". | 
|  | NonNestableBlock(Scope* scope, | 
|  | const FunctionCallNode* function, | 
|  | const char* type_description); | 
|  | ~NonNestableBlock(); | 
|  |  | 
|  | bool Enter(Err* err); | 
|  |  | 
|  | private: | 
|  | // Used as a void* key for the Scope to track our property. The actual value | 
|  | // is never used. | 
|  | static const int kKey; | 
|  |  | 
|  | Scope* scope_; | 
|  | const FunctionCallNode* function_; | 
|  | const char* type_description_; | 
|  |  | 
|  | // Set to true when the key is added to the scope so we don't try to | 
|  | // delete nonexistant keys which will cause assertions. | 
|  | bool key_added_; | 
|  | }; | 
|  |  | 
|  | #endif  // TOOLS_GN_FUNCTIONS_H_ |