| // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "gn/err.h" | 
 | #include "gn/functions.h" | 
 | #include "gn/parse_tree.h" | 
 | #include "gn/scope.h" | 
 |  | 
 | namespace functions { | 
 |  | 
 | const char kSetDefaults[] = "set_defaults"; | 
 | const char kSetDefaults_HelpShort[] = | 
 |     "set_defaults: Set default values for a target type."; | 
 | const char kSetDefaults_Help[] = | 
 |     R"(set_defaults: Set default values for a target type. | 
 |  | 
 |   set_defaults(<target_type_name>) { <values...> } | 
 |  | 
 |   Sets the default values for a given target type. Whenever target_type_name is | 
 |   seen in the future, the values specified in set_default's block will be | 
 |   copied into the current scope. | 
 |  | 
 |   When the target type is used, the variable copying is very strict. If a | 
 |   variable with that name is already in scope, the build will fail with an | 
 |   error. | 
 |  | 
 |   set_defaults can be used for built-in target types ("executable", | 
 |   "shared_library", etc.) and custom ones defined via the "template" command. | 
 |   It can be called more than once and the most recent call in any scope will | 
 |   apply, but there is no way to refer to the previous defaults and modify them | 
 |   (each call to set_defaults must supply a complete list of all defaults it | 
 |   wants). If you want to share defaults, store them in a separate variable. | 
 |  | 
 | Example | 
 |  | 
 |   set_defaults("static_library") { | 
 |     configs = [ "//tools/mything:settings" ] | 
 |   } | 
 |  | 
 |   static_library("mylib") { | 
 |     # The configs will be auto-populated as above. You can remove it if | 
 |     # you don't want the default for a particular default: | 
 |     configs -= [ "//tools/mything:settings" ] | 
 |   } | 
 | )"; | 
 |  | 
 | Value RunSetDefaults(Scope* scope, | 
 |                      const FunctionCallNode* function, | 
 |                      const std::vector<Value>& args, | 
 |                      BlockNode* block, | 
 |                      Err* err) { | 
 |   if (!EnsureSingleStringArg(function, args, err)) | 
 |     return Value(); | 
 |   const std::string& target_type(args[0].string_value()); | 
 |  | 
 |   if (!block) { | 
 |     FillNeedsBlockError(function, err); | 
 |     return Value(); | 
 |   } | 
 |  | 
 |   // Run the block for the rule invocation. | 
 |   Scope block_scope(scope); | 
 |   block->Execute(&block_scope, err); | 
 |   if (err->has_error()) | 
 |     return Value(); | 
 |  | 
 |   // Now copy the values set on the scope we made into the free-floating one | 
 |   // (with no containing scope) used to hold the target defaults. | 
 |   Scope* dest = scope->MakeTargetDefaults(target_type); | 
 |   block_scope.NonRecursiveMergeTo(dest, Scope::MergeOptions(), function, | 
 |                                   "<SHOULD NOT FAIL>", err); | 
 |   return Value(); | 
 | } | 
 |  | 
 | }  // namespace functions |