functions.cc revision d3868032626d59662ff73b372b5d584c1d144c53
1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file. 4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <iostream> 8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/string_util.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config_values_generator.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h" 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/input_file.h" 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/item_tree.h" 15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h" 16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h" 17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h" 18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/settings.h" 19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target_manager.h" 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h" 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h" 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace { 24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid FillNeedsBlockError(const FunctionCallNode* function, Err* err) { 26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "This function call requires a block.", 27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "The block's \"{\" must be on the same line as the function " 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "call's \")\"."); 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 31d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteAssert(const FunctionCallNode* function, 32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args.size() != 1) { 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "Wrong number of arguments.", 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "assert() takes one argument, " 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "were you expecting somethig else?"); 38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else if (args[0].InterpretAsInt() == 0) { 39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "Assertion failed."); 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args[0].origin()) { 41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // If you do "assert(foo)" we'd ideally like to show you where foo was 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // set, and in this case the origin of the args will tell us that. 43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // However, if you do "assert(foo && bar)" the source of the value will 44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // be the assert like, which isn't so helpful. 45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // 46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // So we try to see if the args are from the same line or not. This will 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // break if you do "assert(\nfoo && bar)" and we may show the second line 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // as the source, oh well. The way around this is to check to see if the 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // origin node is inside our function call block. 50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Location origin_location = args[0].origin()->GetRange().begin(); 51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (origin_location.file() != function->function().location().file() || 52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch origin_location.line_number() != 53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch function->function().location().line_number()) { 54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err->AppendSubErr(Err(args[0].origin()->GetRange(), "", 55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This is where it was set.")); 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 62d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteConfig(Scope* scope, 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureSingleStringArg(function, args, err) || 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch !EnsureNotProcessingImport(function, scope, err)) 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Label label(MakeLabelForScope(scope, function, args[0].string_value())); 71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (g_scheduler->verbose_logging()) 73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch g_scheduler->Log("Generating config", label.GetUserVisibleName(true)); 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Create the empty config object. 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ItemTree* tree = &scope->settings()->build_settings()->item_tree(); 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Config* config = Config::GetConfig(scope->settings(), function->GetRange(), 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch label, NULL, err); 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Fill it. 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const SourceDir input_dir = SourceDirForFunctionCall(function); 84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ConfigValuesGenerator gen(&config->config_values(), scope, 85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch function->function(), input_dir, err); 86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch gen.Run(); 87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Mark as complete. 91d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch { 92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::AutoLock lock(tree->lock()); 93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch tree->MarkItemGeneratedLocked(label); 94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 98d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteDeclareArgs(Scope* scope, 99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Only allow this to be called once. We use a variable in the current scope 103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // with a name the parser will reject if the user tried to type it. 104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const char did_declare_args_var[] = "@@declared_args"; 105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (scope->GetValue(did_declare_args_var)) { 106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "Duplicate call to declared_args."); 107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err->AppendSubErr( 108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err(scope->GetValue(did_declare_args_var)->origin()->GetRange(), 109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "See the original call.")); 110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 113d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Find the root scope where the values will be set. 114d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope* root = scope->mutable_containing(); 115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!root || root->containing() || !scope->IsProcessingBuildConfig()) { 116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "declare_args called incorrectly." 117d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "It must be called only from the build config script and in the " 118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "root scope."); 119d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 120d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 121d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 122d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Take all variables set in the current scope as default values and put 123d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // them in the parent scope. The values in the current scope are the defaults, 124d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // then we apply the external args to this list. 125d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope::KeyValueVector values; 126d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->GetCurrentScopeValues(&values); 127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < values.size(); i++) { 128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // TODO(brettw) actually import the arguments from the command line rather 129d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // than only using the defaults. 130d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch root->SetValue(values[i].first, values[i].second, 131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch values[i].second.origin()); 132d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 133d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->SetValue(did_declare_args_var, Value(function, 1), NULL); 135d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 138d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteImport(Scope* scope, 139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 141d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 142d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureSingleStringArg(function, args, err) || 143d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch !EnsureNotProcessingImport(function, scope, err)) 144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const SourceDir input_dir = SourceDirForFunctionCall(function); 147d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SourceFile import_file = 148d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch input_dir.ResolveRelativeFile(args[0].string_value()); 149d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->settings()->import_manager().DoImport(import_file, function, 150d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope, err); 151d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 153d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 154d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteTemplate(Scope* scope, 155d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* invocation, 156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch BlockNode* block, 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* rule, 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureNotProcessingImport(invocation, scope, err)) 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope block_scope(scope); 163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!FillTargetBlockScope(scope, invocation, 164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch invocation->function().value().data(), 165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block, args, &block_scope, err)) 166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Run the block for the rule invocation. 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block->ExecuteBlockInScope(&block_scope, err); 170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Now run the rule itself with that block as the current scope. 174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch rule->block()->ExecuteBlockInScope(&block_scope, err); 175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 176d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 177d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 178d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 179d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 180d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 181d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteSetDefaults(Scope* scope, 182d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 184d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch BlockNode* block, 185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureSingleStringArg(function, args, err)) 187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& target_type(args[0].string_value()); 189d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 190d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Ensure there aren't defaults already set. 191d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (scope->GetTargetDefaults(target_type)) { 192d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), 193d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This target type defaults were already set."); 194d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 195d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 196d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 197d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Execute the block in a new scope that has a parent of the containing 198d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // scope. 199d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope block_scope(scope); 200d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!FillTargetBlockScope(scope, function, 201d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch function->function().value().data(), 202d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block, args, &block_scope, err)) 203d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Run the block for the rule invocation. 206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block->ExecuteBlockInScope(&block_scope, err); 207d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Now copy the values set on the scope we made into the free-floating one 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // (with no containing scope) used to hold the target defaults. 212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope* dest = scope->MakeTargetDefaults(target_type); 213d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block_scope.NonRecursiveMergeTo(dest, function, "<SHOULD NOT FAIL>", err); 214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 215d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 217d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteSetSourcesAssignmentFilter(Scope* scope, 218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 220d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 221d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args.size() != 1) { 222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function, "set_sources_assignment_filter takes one argument."); 223d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<PatternList> f(new PatternList); 225d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch f->SetFromValue(args[0], err); 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!err->has_error()) 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->set_sources_assignment_filter(f.Pass()); 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// void print(...) 233d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// prints all arguments to the console separated by spaces. 234d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecutePrint(const std::vector<Value>& args, Err* err) { 235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < args.size(); i++) { 236d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (i != 0) 237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::cout << " "; 238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::cout << args[i].ToString(); 239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 240d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::cout << std::endl; 241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 242d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ---------------------------------------------------------------------------- 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace functions { 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kAssert[] = "assert"; 251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kComponent[] = "component"; 252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kConfig[] = "config"; 253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kCopy[] = "copy"; 254d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kCustom[] = "custom"; 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kDeclareArgs[] = "declare_args"; 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kExecScript[] = "exec_script"; 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kExecutable[] = "executable"; 258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kGroup[] = "group"; 259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kImport[] = "import"; 260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kPrint[] = "print"; 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kProcessFileTemplate[] = "process_file_template"; 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kReadFile[] = "read_file"; 263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kSetDefaults[] = "set_defaults"; 264d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kSetDefaultToolchain[] = "set_default_toolchain"; 265d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; 266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kSharedLibrary[] = "shared_library"; 267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kStaticLibrary[] = "static_library"; 268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kTemplate[] = "template"; 269d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kTool[] = "tool"; 270d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kToolchain[] = "toolchain"; 271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kTest[] = "test"; 272d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kWriteFile[] = "write_file"; 273d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 274d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace functions 275d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ---------------------------------------------------------------------------- 277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EnsureNotProcessingImport(const ParseNode* node, 279d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Scope* scope, 280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (scope->IsProcessingImport()) { 282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(node, "Not valid from an import.", 283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "We need to talk about this thing you are doing here. Doing this\n" 284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "kind of thing from an imported file makes me feel like you are\n" 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "abusing me. Imports are for defining defaults, variables, and rules.\n" 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "The appropriate place for this kind of thing is really in a normal\n" 287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "BUILD file."); 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EnsureNotProcessingBuildConfig(const ParseNode* node, 294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Scope* scope, 295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (scope->IsProcessingBuildConfig()) { 297d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(node, "Not valid from the build config.", 298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "You can't do this kind of thing from the build config script, " 299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "silly!\nPut it in a regular BUILD file."); 300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 303d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 304d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 305d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool FillTargetBlockScope(const Scope* scope, 306d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const char* target_type, 308d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const BlockNode* block, 309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope* block_scope, 311d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!block) { 313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch FillNeedsBlockError(function, err); 314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 315d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 316d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 317d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Copy the target defaults, if any, into the scope we're going to execute 318d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // the block in. 319d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Scope* default_scope = scope->GetTargetDefaults(target_type); 320d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (default_scope) { 321d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!default_scope->NonRecursiveMergeTo(block_scope, function, 322d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "target defaults", err)) 323d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 324d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 325d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The name is the single argument to the target function. 327d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureSingleStringArg(function, args, err)) 328d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 329d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 330d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Set the target name variable to the current target, and mark it used 331d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // because we don't want to issue an error if the script ignores it. 332d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::StringPiece target_name("target_name"); 333d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block_scope->SetValue(target_name, Value(function, args[0].string_value()), 334d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch function); 335d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block_scope->MarkUsed(target_name); 336d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return true; 337d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 338d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 339d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool EnsureSingleStringArg(const FunctionCallNode* function, 340d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 341d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 342d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args.size() != 1) { 343d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "Incorrect arguments.", 344d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This function requires a single string argument."); 345d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return false; 346d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 347d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return args[0].VerifyTypeIs(Value::STRING, err); 348d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 349d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 350d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst SourceDir& SourceDirForFunctionCall(const FunctionCallNode* function) { 351d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return function->function().location().file()->dir(); 352d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 353d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 354d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst Label& ToolchainLabelForScope(const Scope* scope) { 355d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return scope->settings()->toolchain()->label(); 356d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 357d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 358d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLabel MakeLabelForScope(const Scope* scope, 359d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 360d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& name) { 361d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const SourceDir& input_dir = SourceDirForFunctionCall(function); 362d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Label& toolchain_label = ToolchainLabelForScope(scope); 363d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Label(input_dir, name, toolchain_label.dir(), toolchain_label.name()); 364d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 365d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 366d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ExecuteFunction(Scope* scope, 367d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* function, 368d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::vector<Value>& args, 369d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch BlockNode* block, 370d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Err* err) { 371d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Token& name = function->function(); 372d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (block) { 373d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // These target generators need to execute the block themselves. 374d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kComponent)) 375d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteComponent(scope, function, args, block, err); 376d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kCustom)) 377d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteCustom(scope, function, args, block, err); 378d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kExecutable)) 379d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteExecutable(scope, function, args, block, err); 380d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kSetDefaults)) 381d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteSetDefaults(scope, function, args, block, err); 382d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kSharedLibrary)) 383d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteSharedLibrary(scope, function, args, block, err); 384d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kStaticLibrary)) 385d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteStaticLibrary(scope, function, args, block, err); 386d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kGroup)) 387d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteGroup(scope, function, args, block, err); 388d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kTest)) 389d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteExecutable(scope, function, args, block, err); 390d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kTemplate)) 391d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteTemplate(scope, function, args, block, err); 392d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kTool)) 393d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteTool(scope, function, args, block, err); 394d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kToolchain)) 395d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteToolchain(scope, function, args, block, err); 396d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 397d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const FunctionCallNode* rule = 398d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->GetTemplate(function->function().value().as_string()); 399d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (rule) 400d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteTemplate(scope, function, args, block, rule, err); 401d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 402d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // FIXME(brettw) This is not right, what if you specify a function that 403d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // doesn't take a block but specify one?!?!? 404d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 405d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The rest of the functions can take a pre-executed block for simplicity. 406d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope block_scope(scope); 407d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block->ExecuteBlockInScope(&block_scope, err); 408d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 409d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 410d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 411d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kConfig)) 412d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteConfig(&block_scope, function, args, err); 413d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kCopy)) 414d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteCopy(&block_scope, function, args, err); 415d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kDeclareArgs)) 416d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteDeclareArgs(&block_scope, function, args, err); 417d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 418d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(name, "Unknown function."); 419d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 420d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 421d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 422d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kAssert)) 423d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteAssert(function, args, err); 424d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kExecScript)) 425d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteExecScript(scope, function, args, err); 426d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kImport)) 427d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteImport(scope, function, args, err); 428d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kPrint)) 429d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecutePrint(args, err); 430d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kProcessFileTemplate)) 431d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteProcessFileTemplate(scope, function, args, err); 432d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kReadFile)) 433d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteReadFile(scope, function, args, err); 434d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kSetDefaultToolchain)) 435d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteSetDefaultToolchain(scope, function, args, err); 436d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kSetSourcesAssignmentFilter)) 437d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteSetSourcesAssignmentFilter(scope, function, args, err); 438d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (name.IsIdentifierEqualTo(functions::kWriteFile)) 439d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteWriteFile(scope, function, args, err); 440d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 441d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function, "Unknown function."); 442d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 443d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 444