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 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/environment.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/string_util.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config_values_generator.h" 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h" 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/input_file.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" 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "tools/gn/template.h" 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h" 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h" 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool EnsureNotProcessingImport(const ParseNode* node, 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Scope* scope, 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (scope->IsProcessingImport()) { 27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(node, "Not valid from an import.", 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "Imports are for defining defaults, variables, and rules. The\n" 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "appropriate place for this kind of thing is really in a normal\n" 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "BUILD file."); 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool EnsureNotProcessingBuildConfig(const ParseNode* node, 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Scope* scope, 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (scope->IsProcessingBuildConfig()) { 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(node, "Not valid from the build config.", 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "You can't do this kind of thing from the build config script, " 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "silly!\nPut it in a regular BUILD file."); 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool FillTargetBlockScope(const Scope* scope, 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& target_type, 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const BlockNode* block, 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Scope* block_scope, 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!block) { 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FillNeedsBlockError(function, err); 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Copy the target defaults, if any, into the scope we're going to execute 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the block in. 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Scope* default_scope = scope->GetTargetDefaults(target_type); 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (default_scope) { 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Scope::MergeOptions merge_options; 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) merge_options.skip_private_vars = true; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!default_scope->NonRecursiveMergeTo(block_scope, merge_options, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function, "target defaults", err)) 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The name is the single argument to the target function. 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!EnsureSingleStringArg(function, args, err)) 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Set the target name variable to the current target, and mark it used 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // because we don't want to issue an error if the script ignores it. 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::StringPiece target_name("target_name"); 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) block_scope->SetValue(target_name, Value(function, args[0].string_value()), 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) function); 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) block_scope->MarkUsed(target_name); 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FillNeedsBlockError(const FunctionCallNode* function, Err* err) { 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "This function call requires a block.", 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "The block's \"{\" must be on the same line as the function " 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "call's \")\"."); 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool EnsureSingleStringArg(const FunctionCallNode* function, 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (args.size() != 1) { 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(function->function(), "Incorrect arguments.", 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "This function requires a single string argument."); 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return args[0].VerifyTypeIs(Value::STRING, err); 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const Label& ToolchainLabelForScope(const Scope* scope) { 1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return scope->settings()->toolchain_label(); 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Label MakeLabelForScope(const Scope* scope, 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& name) { 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Label& toolchain_label = ToolchainLabelForScope(scope); 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Label(scope->GetSourceDir(), name, toolchain_label.dir(), 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) toolchain_label.name()); 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace functions { 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// assert ---------------------------------------------------------------------- 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kAssert[] = "assert"; 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kAssert_HelpShort[] = 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "assert: Assert an expression is true at generation time."; 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kAssert_Help[] = 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "assert: Assert an expression is true at generation time.\n" 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " assert(<condition> [, <error string>])\n" 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " If the condition is false, the build will fail with an error. If the\n" 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " optional second argument is provided, that string will be printed\n" 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " with the error message.\n" 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Examples:\n" 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " assert(is_win)\n" 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " assert(defined(sources), \"Sources must be defined\")\n"; 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunAssert(Scope* scope, 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (args.size() != 1 && args.size() != 2) { 138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "Wrong number of arguments.", 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "assert() takes one or two argument, " 140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "were you expecting somethig else?"); 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (args[0].type() != Value::BOOLEAN) { 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion value not a bool."); 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (!args[0].boolean_value()) { 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (args.size() == 2) { 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Optional string message. 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (args[1].type() != Value::STRING) { 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion failed.", 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "<<<ERROR MESSAGE IS NOT A STRING>>>"); 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion failed.", 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args[1].string_value()); 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion failed."); 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args[0].origin()) { 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // If you do "assert(foo)" we'd ideally like to show you where foo was 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // set, and in this case the origin of the args will tell us that. 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // However, if you do "assert(foo && bar)" the source of the value will 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // be the assert like, which isn't so helpful. 162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // 163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // So we try to see if the args are from the same line or not. This will 164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // break if you do "assert(\nfoo && bar)" and we may show the second line 165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // as the source, oh well. The way around this is to check to see if the 166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // origin node is inside our function call block. 167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Location origin_location = args[0].origin()->GetRange().begin(); 168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (origin_location.file() != function->function().location().file() || 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch origin_location.line_number() != 170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch function->function().location().line_number()) { 171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err->AppendSubErr(Err(args[0].origin()->GetRange(), "", 172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This is where it was set.")); 173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 176d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 177d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 178d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// config ---------------------------------------------------------------------- 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kConfig[] = "config"; 182e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kConfig_HelpShort[] = 183e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "config: Defines a configuration object."; 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kConfig_Help[] = 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "config: Defines a configuration object.\n" 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " Configuration objects can be applied to targets and specify sets of\n" 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " compiler flags, includes, defines, etc. They provide a way to\n" 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " conveniently group sets of this configuration information.\n" 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " A config is referenced by its label just like a target.\n" 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " The values in a config are additive only. If you want to remove a flag\n" 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " you need to remove the corresponding config that sets it. The final\n" 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " set of flags, defines, etc. for a target is generated in this order:\n" 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 1. The values specified directly on the target (rather than using a\n" 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " config.\n" 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 2. The configs specified in the target's \"configs\" list, in order.\n" 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " 3. Public_configs from a breadth-first traversal of the dependency\n" 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " tree in the order that the targets appear in \"deps\".\n" 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 4. All dependent configs from a breadth-first traversal of the\n" 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " dependency tree in the order that the targets appear in \"deps\".\n" 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Variables valid in a config definition:\n" 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CONFIG_VALUES_VARS_HELP 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Variables on a target used to apply configs:\n" 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " all_dependent_configs, configs, public_configs,\n" 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " forward_dependent_configs_from\n" 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Example:\n" 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " config(\"myconfig\") {\n" 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " includes = [ \"include/common\" ]\n" 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " defines = [ \"ENABLE_DOOM_MELON\" ]\n" 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " }\n" 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " executable(\"mything\") {\n" 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " configs = [ \":myconfig\" ]\n" 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " }\n"; 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunConfig(const FunctionCallNode* function, 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Scope* scope, 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureSingleStringArg(function, args, err) || 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch !EnsureNotProcessingImport(function, scope, err)) 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Label label(MakeLabelForScope(scope, function, args[0].string_value())); 231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (g_scheduler->verbose_logging()) 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g_scheduler->Log("Defining config", label.GetUserVisibleName(true)); 234d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Create the new config. 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<Config> config(new Config(scope->settings(), label)); 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) config->set_defined_from(function); 238e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!Visibility::FillItemVisibility(config.get(), scope, err)) 239e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return Value(); 240d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Fill it. 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const SourceDir& input_dir = scope->GetSourceDir(); 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConfigValuesGenerator gen(&config->config_values(), scope, input_dir, err); 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch gen.Run(); 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Save the generated item. 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Scope::ItemVector* collector = scope->GetItemCollector(); 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!collector) { 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *err = Err(function, "Can't define a config in this context."); 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return Value(); 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) collector->push_back(new scoped_ptr<Item>(config.PassAs<Item>())); 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// declare_args ---------------------------------------------------------------- 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kDeclareArgs[] = "declare_args"; 262e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kDeclareArgs_HelpShort[] = 263e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "declare_args: Declare build arguments."; 264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kDeclareArgs_Help[] = 265e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "declare_args: Declare build arguments.\n" 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " Introduces the given arguments into the current scope. If they are\n" 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " not specified on the command line or in a toolchain's arguments,\n" 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " the default values given in the declare_args block will be used.\n" 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " However, these defaults will not override command-line values.\n" 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " See also \"gn help buildargs\" for an overview.\n" 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Example:\n" 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " declare_args() {\n" 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " enable_teleporter = true\n" 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " enable_doom_melon = false\n" 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " }\n" 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " If you want to override the (default disabled) Doom Melon:\n" 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n" 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " This also sets the teleporter, but it's already defaulted to on so\n" 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " it will have no effect.\n"; 284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Value RunDeclareArgs(Scope* scope, 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FunctionCallNode* function, 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BlockNode* block, 289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Scope block_scope(scope); 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) block->ExecuteBlockInScope(&block_scope, err); 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err->has_error()) 293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Pass the values from our scope into the Args object for adding to the 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // scope with the proper values (taking into account the defaults given in 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the block_scope, and arguments passed into the build). 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Scope::KeyValueMap values; 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) block_scope.GetCurrentScopeValues(&values); 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scope->settings()->build_settings()->build_args().DeclareArgs( 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) values, scope, err); 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// defined --------------------------------------------------------------------- 306d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kDefined[] = "defined"; 308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kDefined_HelpShort[] = 309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "defined: Returns whether an identifier is defined."; 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kDefined_Help[] = 3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "defined: Returns whether an identifier is defined.\n" 3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " Returns true if the given argument is defined. This is most useful in\n" 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " templates to assert that the caller set things up properly.\n" 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 316effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " You can pass an identifier:\n" 317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " defined(foo)\n" 318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " which will return true or false depending on whether foo is defined in\n" 319effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " the current scope.\n" 320effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "\n" 321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " You can also check a named scope:\n" 322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " defined(foo.bar)\n" 323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " which returns true if both foo is defined and bar is defined on the\n" 324effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " named scope foo. It will throw an error if foo is defined but is not\n" 325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " a scope.\n" 326effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "\n" 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Example:\n" 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " template(\"mytemplate\") {\n" 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " # To help users call this template properly...\n" 331effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " assert(defined(invoker.sources), \"Sources must be defined\")\n" 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " # If we want to accept an optional \"values\" argument, we don't\n" 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " # want to dereference something that may not be defined.\n" 335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " if (defined(invoker.values)) {\n" 336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " values = invoker.values\n" 337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " } else {\n" 338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " values = \"some default value\"\n" 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " }\n" 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " }\n"; 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Value RunDefined(Scope* scope, 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FunctionCallNode* function, 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ListNode* args_list, 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Err* err) { 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::vector<const ParseNode*>& args_vector = args_list->contents(); 347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (args_vector.size() != 1) { 348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *err = Err(function, "Wrong number of arguments to defined().", 349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "Expecting exactly one."); 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 351d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 352d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IdentifierNode* identifier = args_vector[0]->AsIdentifier(); 354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (identifier) { 355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Passed an identifier "defined(foo)". 356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (scope->GetValue(identifier->value().value())) 357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, true); 358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, false); 359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const AccessorNode* accessor = args_vector[0]->AsAccessor(); 362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (accessor) { 363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Passed an accessor "defined(foo.bar)". 364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (accessor->member()) { 365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // The base of the accessor must be a scope if it's defined. 366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Value* base = scope->GetValue(accessor->base().value()); 367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!base) 368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, false); 369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!base->VerifyTypeIs(Value::SCOPE, err)) 370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Check the member inside the scope to see if its defined. 373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (base->scope_value()->GetValue(accessor->member()->value().value())) 374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, true); 375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, false); 376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Argument is invalid. 380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *err = Err(function, "Bad thing passed to defined().", 381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "It should be of the form defined(foo) or defined(foo.bar)."); 382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 383d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 384d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// getenv ---------------------------------------------------------------------- 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kGetEnv[] = "getenv"; 388e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kGetEnv_HelpShort[] = 389e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "getenv: Get an environment variable."; 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kGetEnv_Help[] = 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "getenv: Get an environment variable.\n" 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " value = getenv(env_var_name)\n" 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " Returns the value of the given enironment variable. If the value is\n" 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " not found, it will try to look up the variable with the \"opposite\"\n" 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " case (based on the case of the first letter of the variable), but\n" 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " is otherwise case-sensitive.\n" 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " If the environment variable is not found, the empty string will be\n" 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " returned. Note: it might be nice to extend this if we had the concept\n" 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " of \"none\" in the language to indicate lookup failure.\n" 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Example:\n" 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " home_dir = getenv(\"HOME\")\n"; 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Value RunGetEnv(Scope* scope, 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const FunctionCallNode* function, 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<Value>& args, 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Err* err) { 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!EnsureSingleStringArg(function, args, err)) 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Value(); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string result; 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!env->GetVar(args[0].string_value().c_str(), &result)) 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Value(function, ""); // Not found, return empty string. 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Value(function, result); 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// import ---------------------------------------------------------------------- 424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kImport[] = "import"; 426e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kImport_HelpShort[] = 427e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "import: Import a file into the current scope."; 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kImport_Help[] = 429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "import: Import a file into the current scope.\n" 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " The import command loads the rules and variables resulting from\n" 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " executing the given file into the current scope.\n" 433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " By convention, imported files are named with a .gni extension.\n" 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " An import is different than a C++ \"include\". The imported file is\n" 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " executed in a standalone environment from the caller of the import\n" 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " command. The results of this execution are cached for other files that\n" 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " import the same .gni file.\n" 440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " Note that you can not import a BUILD.gn file that's otherwise used\n" 442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " in the build. Files must either be imported or implicitly loaded as\n" 443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " a result of deps rules, but not both.\n" 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " The imported file's scope will be merged with the scope at the point\n" 446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " import was called. If there is a conflict (both the current scope and\n" 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " the imported file define some variable or rule with the same name but\n" 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " different value), a runtime error will be thrown. Therefore, it's good\n" 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " practice to minimize the stuff that an imported file defines.\n" 450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " Variables and templates beginning with an underscore '_' are\n" 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " considered private and will not be imported. Imported files can use\n" 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) " such variables for internal computation without affecting other files.\n" 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "\n" 455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Examples:\n" 456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " import(\"//build/rules/idl_compilation_rule.gni\")\n" 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " # Looks in the current directory.\n" 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " import(\"my_vars.gni\")\n"; 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunImport(Scope* scope, 463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!EnsureSingleStringArg(function, args, err)) 467d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 468d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const SourceDir& input_dir = scope->GetSourceDir(); 470d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SourceFile import_file = 471d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch input_dir.ResolveRelativeFile(args[0].string_value()); 472d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->settings()->import_manager().DoImport(import_file, function, 473d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope, err); 474d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 475d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 476d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// set_sources_assignment_filter ----------------------------------------------- 478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; 480e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kSetSourcesAssignmentFilter_HelpShort[] = 481e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "set_sources_assignment_filter: Set a pattern to filter source files."; 482a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kSetSourcesAssignmentFilter_Help[] = 48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "set_sources_assignment_filter: Set a pattern to filter source files.\n" 48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " The sources assignment filter is a list of patterns that remove files\n" 48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " from the list implicitly whenever the \"sources\" variable is\n" 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " assigned to. This is intended to be used to globally filter out files\n" 48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " with platform-specific naming schemes when they don't apply, for\n" 48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " example, you may want to filter out all \"*_win.cc\" files on non-\n" 49068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " Windows platforms.\n" 49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " Typically this will be called once in the master build config script\n" 49368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " to set up the filter for the current platform. Subsequent calls will\n" 49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " overwrite the previous values.\n" 49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " If you want to bypass the filter and add a file even if it might\n" 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " be filtered out, call set_sources_assignment_filter([]) to clear the\n" 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " list of filters. This will apply until the current scope exits\n" 49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "How to use patterns\n" 5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " File patterns are VERY limited regular expressions. They must match\n" 5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " the entire input string to be counted as a match. In regular\n" 5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " expression parlance, there is an implicit \"^...$\" surrounding your\n" 5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " input. If you want to match a substring, you need to use wildcards at\n" 5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " the beginning and end.\n" 5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " There are only two special tokens understood by the pattern matcher.\n" 5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " Everything else is a literal.\n" 5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " * Matches zero or more of any character. It does not depend on the\n" 5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " preceding character (in regular expression parlance it is\n" 5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " equivalent to \".*\").\n" 5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " \\b Matches a path boundary. This will match the beginning or end of\n" 5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " a string, or a slash.\n" 5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Pattern examples\n" 5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " \"*asdf*\"\n" 5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " Matches a string containing \"asdf\" anywhere.\n" 5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " \"asdf\"\n" 5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " Matches only the exact string \"asdf\".\n" 5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " \"*.cc\"\n" 5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " Matches strings ending in the literal \".cc\".\n" 5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " \"\\bwin/*\"\n" 5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " Matches \"win/foo\" and \"foo/win/bar.cc\" but not \"iwin/foo\".\n" 5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Sources assignment example\n" 5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "\n" 53468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " # Filter out all _win files.\n" 5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " set_sources_assignment_filter([ \"*_win.cc\", \"*_win.h\" ])\n" 5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " sources = [ \"a.cc\", \"b_win.cc\" ]\n" 5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " print(sources)\n" 5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci " # Will print [ \"a.cc\" ]. b_win one was filtered out.\n"; 539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 540a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunSetSourcesAssignmentFilter(Scope* scope, 541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 544d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args.size() != 1) { 545d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function, "set_sources_assignment_filter takes one argument."); 546d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 547d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<PatternList> f(new PatternList); 548d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch f->SetFromValue(args[0], err); 549d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!err->has_error()) 550d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->set_sources_assignment_filter(f.Pass()); 551d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 552d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 553d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 554d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// print ----------------------------------------------------------------------- 556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 557a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kPrint[] = "print"; 558e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kPrint_HelpShort[] = 559e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "print: Prints to the console."; 560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kPrint_Help[] = 561e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "print: Prints to the console.\n" 562e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "\n" 563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " Prints all arguments to the console separated by spaces. A newline is\n" 564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " automatically appended to the end.\n" 565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " This function is intended for debugging. Note that build files are run\n" 567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " in parallel so you may get interleaved prints. A buildfile may also\n" 568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " be executed more than once in parallel in the context of different\n" 569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " toolchains so the prints from one file may be duplicated or\n" 570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " interleaved with itself.\n" 571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Examples:\n" 573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " print(\"Hello world\")\n" 574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " print(sources, deps)\n"; 576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunPrint(Scope* scope, 578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 581c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string output; 582d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < args.size(); i++) { 583d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (i != 0) 584c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output.push_back(' '); 585c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output.append(args[i].ToString(false)); 586d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 587c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output.push_back('\n'); 588c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 589c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const BuildSettings::PrintCallback& cb = 590c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scope->settings()->build_settings()->print_callback(); 591c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (cb.is_null()) 592c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch printf("%s", output.c_str()); 593c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else 594c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cb.Run(output); 595c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 596d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 597d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 598d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// ----------------------------------------------------------------------------- 600d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)FunctionInfo::FunctionInfo() 6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(NULL), 605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(NULL), 606e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(NULL), 607e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(NULL), 608e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(false) { 609d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 610d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 611e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(SelfEvaluatingArgsFunction seaf, 612e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 613e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 614e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(seaf), 6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 6173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) executed_block_runner(NULL), 6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) no_block_runner(NULL), 619e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 620e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 621e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 624e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(GenericBlockFunction gbf, 625e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 626e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 627e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(gbf), 630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(NULL), 631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(NULL), 632e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 633e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 634e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 635d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 636d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 637e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(ExecutedBlockFunction ebf, 638e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 639e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 640e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(ebf), 644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(NULL), 645e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 646e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 647e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 648d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 649d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 650e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(NoBlockFunction nbf, 651e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 652e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 653e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 6553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 656a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(NULL), 657a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(nbf), 658e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 659e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 660e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 661d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 662d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Setup the function map via a static initializer. We use this because it 664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// avoids race conditions without having to do some global setup function or 665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// locking-heavy singleton checks at runtime. In practice, we always need this 666a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// before we can do anything interesting, so it's OK to wait for the 667a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// initializer. 668a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)struct FunctionInfoInitializer { 669a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionInfoMap map; 670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 671a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionInfoInitializer() { 672e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch #define INSERT_FUNCTION(command, is_target) \ 673e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch map[k##command] = FunctionInfo(&Run##command, \ 674e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch k##command##_HelpShort, \ 675e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch k##command##_Help, \ 676e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target); 677e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 678e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Action, true) 679e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ActionForEach, true) 680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) INSERT_FUNCTION(Copy, true) 681e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Executable, true) 682e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Group, true) 683e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SharedLibrary, true) 684e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SourceSet, true) 685e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(StaticLibrary, true) 686e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 687e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Assert, false) 688e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Config, false) 689e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(DeclareArgs, false) 690e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Defined, false) 691e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ExecScript, false) 692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) INSERT_FUNCTION(ForEach, false) 693e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(GetEnv, false) 694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) INSERT_FUNCTION(GetLabelInfo, false) 69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) INSERT_FUNCTION(GetPathInfo, false) 696010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) INSERT_FUNCTION(GetTargetOutputs, false) 697e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Import, false) 698e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Print, false) 699e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ProcessFileTemplate, false) 700e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ReadFile, false) 701e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(RebasePath, false) 702e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SetDefaults, false) 703e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SetDefaultToolchain, false) 704e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SetSourcesAssignmentFilter, false) 705e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Template, false) 706e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Tool, false) 707e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Toolchain, false) 708e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ToolchainArgs, false) 709e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(WriteFile, false) 710a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 711a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) #undef INSERT_FUNCTION 712a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 713a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 714a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const FunctionInfoInitializer function_info; 715d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const FunctionInfoMap& GetFunctions() { 717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return function_info.map; 718d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 719d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunFunction(Scope* scope, 721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ListNode* args_list, 723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) BlockNode* block, 724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 725d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Token& name = function->function(); 726d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 727a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionInfoMap& function_map = GetFunctions(); 728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionInfoMap::const_iterator found_function = 729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) function_map.find(name.value()); 730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found_function == function_map.end()) { 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No built-in function matching this, check for a template. 732effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Template* templ = 733d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->GetTemplate(function->function().value().as_string()); 734effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (templ) { 7353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value args = args_list->Execute(scope, err); 7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err->has_error()) 7373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 738effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return templ->Invoke(scope, function, args.list_value(), block, err); 7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 740d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(name, "Unknown function."); 742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Value(); 743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (found_function->second.self_evaluating_args_runner) { 7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return found_function->second.self_evaluating_args_runner( 7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scope, function, args_list, err); 7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // All other function types take a pre-executed set of args. 7513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value args = args_list->Execute(scope, err); 7523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err->has_error()) 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 7543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 755a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found_function->second.generic_block_runner) { 756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!block) { 757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FillNeedsBlockError(function, err); 758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Value(); 759a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 760a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return found_function->second.generic_block_runner( 7613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scope, function, args.list_value(), block, err); 762a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 763a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 764a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found_function->second.executed_block_runner) { 765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!block) { 766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FillNeedsBlockError(function, err); 767a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Value(); 768a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 769d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 770d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope block_scope(scope); 771d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block->ExecuteBlockInScope(&block_scope, err); 772d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 773d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Value result = found_function->second.executed_block_runner( 7763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) function, args.list_value(), &block_scope, err); 7771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (err->has_error()) 7781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return Value(); 7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!block_scope.CheckForUnusedVars(err)) 7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return Value(); 7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return result; 783d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 784d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 785a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Otherwise it's a no-block function. 7863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return found_function->second.no_block_runner(scope, function, 7873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args.list_value(), err); 788d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 789a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 790a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace functions 791