// 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 "tools/gn/functions.h"

#include <stddef.h>
#include <iostream>
#include <memory>
#include <regex>
#include <utility>

#include "base/environment.h"
#include "base/strings/string_util.h"
#include "tools/gn/config.h"
#include "tools/gn/config_values_generator.h"
#include "tools/gn/err.h"
#include "tools/gn/input_file.h"
#include "tools/gn/parse_node_value_adapter.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/pool.h"
#include "tools/gn/scheduler.h"
#include "tools/gn/scope.h"
#include "tools/gn/settings.h"
#include "tools/gn/template.h"
#include "tools/gn/token.h"
#include "tools/gn/value.h"
#include "tools/gn/value_extractors.h"
#include "tools/gn/variables.h"

namespace {

// Some functions take a {} following them, and some don't. For the ones that
// don't, this is used to verify that the given block node is null and will
// set the error accordingly if it's not. Returns true if the block is null.
bool VerifyNoBlockForFunctionCall(const FunctionCallNode* function,
                                  const BlockNode* block,
                                  Err* err) {
  if (!block)
    return true;

  *err =
      Err(block, "Unexpected '{'.",
          "This function call doesn't take a {} block following it, and you\n"
          "can't have a {} block that's not connected to something like an if\n"
          "statement or a target declaration.");
  err->AppendRange(function->function().range());
  return false;
}

// This key is set as a scope property on the scope of a declare_args() block,
// in order to prevent reading a variable defined earlier in the same call
// (see `gn help declare_args` for more).
const void* kInDeclareArgsKey = nullptr;

}  // namespace

bool EnsureNotReadingFromSameDeclareArgs(const ParseNode* node,
                                         const Scope* cur_scope,
                                         const Scope* val_scope,
                                         Err* err) {
  // If the value didn't come from a scope at all, we're safe.
  if (!val_scope)
    return true;

  const Scope* val_args_scope = nullptr;
  val_scope->GetProperty(&kInDeclareArgsKey, &val_args_scope);

  const Scope* cur_args_scope = nullptr;
  cur_scope->GetProperty(&kInDeclareArgsKey, &cur_args_scope);
  if (!val_args_scope || !cur_args_scope || (val_args_scope != cur_args_scope))
    return true;

  *err =
      Err(node,
          "Reading a variable defined in the same declare_args() call.\n"
          "\n"
          "If you need to set the value of one arg based on another, put\n"
          "them in two separate declare_args() calls, one after the other.\n");
  return false;
}

bool EnsureNotProcessingImport(const ParseNode* node,
                               const Scope* scope,
                               Err* err) {
  if (scope->IsProcessingImport()) {
    *err =
        Err(node, "Not valid from an import.",
            "Imports are for defining defaults, variables, and rules. The\n"
            "appropriate place for this kind of thing is really in a normal\n"
            "BUILD file.");
    return false;
  }
  return true;
}

bool EnsureNotProcessingBuildConfig(const ParseNode* node,
                                    const Scope* scope,
                                    Err* err) {
  if (scope->IsProcessingBuildConfig()) {
    *err = Err(node, "Not valid from the build config.",
               "You can't do this kind of thing from the build config script, "
               "silly!\nPut it in a regular BUILD file.");
    return false;
  }
  return true;
}

bool FillTargetBlockScope(const Scope* scope,
                          const FunctionCallNode* function,
                          const std::string& target_type,
                          const BlockNode* block,
                          const std::vector<Value>& args,
                          Scope* block_scope,
                          Err* err) {
  if (!block) {
    FillNeedsBlockError(function, err);
    return false;
  }

  // Copy the target defaults, if any, into the scope we're going to execute
  // the block in.
  const Scope* default_scope = scope->GetTargetDefaults(target_type);
  if (default_scope) {
    Scope::MergeOptions merge_options;
    merge_options.skip_private_vars = true;
    if (!default_scope->NonRecursiveMergeTo(block_scope, merge_options,
                                            function, "target defaults", err))
      return false;
  }

  // The name is the single argument to the target function.
  if (!EnsureSingleStringArg(function, args, err))
    return false;

  // Set the target name variable to the current target, and mark it used
  // because we don't want to issue an error if the script ignores it.
  const base::StringPiece target_name(variables::kTargetName);
  block_scope->SetValue(target_name, Value(function, args[0].string_value()),
                        function);
  block_scope->MarkUsed(target_name);
  return true;
}

void FillNeedsBlockError(const FunctionCallNode* function, Err* err) {
  *err = Err(function->function(), "This function call requires a block.",
             "The block's \"{\" must be on the same line as the function "
             "call's \")\".");
}

bool EnsureSingleStringArg(const FunctionCallNode* function,
                           const std::vector<Value>& args,
                           Err* err) {
  if (args.size() != 1) {
    *err = Err(function->function(), "Incorrect arguments.",
               "This function requires a single string argument.");
    return false;
  }
  return args[0].VerifyTypeIs(Value::STRING, err);
}

const Label& ToolchainLabelForScope(const Scope* scope) {
  return scope->settings()->toolchain_label();
}

Label MakeLabelForScope(const Scope* scope,
                        const FunctionCallNode* function,
                        const std::string& name) {
  const Label& toolchain_label = ToolchainLabelForScope(scope);
  return Label(scope->GetSourceDir(), name, toolchain_label.dir(),
               toolchain_label.name());
}

// static
const int NonNestableBlock::kKey = 0;

NonNestableBlock::NonNestableBlock(Scope* scope,
                                   const FunctionCallNode* function,
                                   const char* type_description)
    : scope_(scope),
      function_(function),
      type_description_(type_description),
      key_added_(false) {}

NonNestableBlock::~NonNestableBlock() {
  if (key_added_)
    scope_->SetProperty(&kKey, nullptr);
}

bool NonNestableBlock::Enter(Err* err) {
  void* scope_value = scope_->GetProperty(&kKey, nullptr);
  if (scope_value) {
    // Existing block.
    const NonNestableBlock* existing =
        reinterpret_cast<const NonNestableBlock*>(scope_value);
    *err = Err(function_, "Can't nest these things.",
               std::string("You are trying to nest a ") + type_description_ +
                   " inside a " + existing->type_description_ + ".");
    err->AppendSubErr(Err(existing->function_, "The enclosing block."));
    return false;
  }

  scope_->SetProperty(&kKey, this);
  key_added_ = true;
  return true;
}

namespace functions {

// assert ----------------------------------------------------------------------

const char kAssert[] = "assert";
const char kAssert_HelpShort[] =
    "assert: Assert an expression is true at generation time.";
const char kAssert_Help[] =
    R"(assert: Assert an expression is true at generation time.

  assert(<condition> [, <error string>])

  If the condition is false, the build will fail with an error. If the
  optional second argument is provided, that string will be printed
  with the error message.

Examples

  assert(is_win)
  assert(defined(sources), "Sources must be defined");
)";

Value RunAssert(Scope* scope,
                const FunctionCallNode* function,
                const std::vector<Value>& args,
                Err* err) {
  if (args.size() != 1 && args.size() != 2) {
    *err = Err(function->function(), "Wrong number of arguments.",
               "assert() takes one or two argument, "
               "were you expecting somethig else?");
  } else if (args[0].type() != Value::BOOLEAN) {
    *err = Err(function->function(), "Assertion value not a bool.");
  } else if (!args[0].boolean_value()) {
    if (args.size() == 2) {
      // Optional string message.
      if (args[1].type() != Value::STRING) {
        *err = Err(function->function(), "Assertion failed.",
                   "<<<ERROR MESSAGE IS NOT A STRING>>>");
      } else {
        *err = Err(function->function(), "Assertion failed.",
                   args[1].string_value());
      }
    } else {
      *err = Err(function->function(), "Assertion failed.");
    }

    if (args[0].origin()) {
      // If you do "assert(foo)" we'd ideally like to show you where foo was
      // set, and in this case the origin of the args will tell us that.
      // However, if you do "assert(foo && bar)" the source of the value will
      // be the assert like, which isn't so helpful.
      //
      // So we try to see if the args are from the same line or not. This will
      // break if you do "assert(\nfoo && bar)" and we may show the second line
      // as the source, oh well. The way around this is to check to see if the
      // origin node is inside our function call block.
      Location origin_location = args[0].origin()->GetRange().begin();
      if (origin_location.file() != function->function().location().file() ||
          origin_location.line_number() !=
              function->function().location().line_number()) {
        err->AppendSubErr(
            Err(args[0].origin()->GetRange(), "", "This is where it was set."));
      }
    }
  }
  return Value();
}

// config ----------------------------------------------------------------------

const char kConfig[] = "config";
const char kConfig_HelpShort[] = "config: Defines a configuration object.";
const char kConfig_Help[] =
    R"(config: Defines a configuration object.

  Configuration objects can be applied to targets and specify sets of compiler
  flags, includes, defines, etc. They provide a way to conveniently group sets
  of this configuration information.

  A config is referenced by its label just like a target.

  The values in a config are additive only. If you want to remove a flag you
  need to remove the corresponding config that sets it. The final set of flags,
  defines, etc. for a target is generated in this order:

   1. The values specified directly on the target (rather than using a config.
   2. The configs specified in the target's "configs" list, in order.
   3. Public_configs from a breadth-first traversal of the dependency tree in
      the order that the targets appear in "deps".
   4. All dependent configs from a breadth-first traversal of the dependency
      tree in the order that the targets appear in "deps".

More background

  Configs solve a problem where the build system needs to have a higher-level
  understanding of various compiler settings. For example, some compiler flags
  have to appear in a certain order relative to each other, some settings like
  defines and flags logically go together, and the build system needs to
  de-duplicate flags even though raw command-line parameters can't always be
  operated on in that way.

  The config gives a name to a group of settings that can then be reasoned
  about by GN. GN can know that configs with the same label are the same thing
  so can be de-duplicated. It allows related settings to be grouped so they
  are added or removed as a unit. And it allows targets to refer to settings
  with conceptual names ("no_rtti", "enable_exceptions", etc.) rather than
  having to hard-coding every compiler's flags each time they are referred to.

Variables valid in a config definition

)"

    CONFIG_VALUES_VARS_HELP

    R"(  Nested configs: configs

Variables on a target used to apply configs

  all_dependent_configs, configs, public_configs

Example

  config("myconfig") {
    include_dirs = [ "include/common" ]
    defines = [ "ENABLE_DOOM_MELON" ]
  }

  executable("mything") {
    configs = [ ":myconfig" ]
  }
)";

Value RunConfig(const FunctionCallNode* function,
                const std::vector<Value>& args,
                Scope* scope,
                Err* err) {
  NonNestableBlock non_nestable(scope, function, "config");
  if (!non_nestable.Enter(err))
    return Value();

  if (!EnsureSingleStringArg(function, args, err) ||
      !EnsureNotProcessingImport(function, scope, err))
    return Value();

  Label label(MakeLabelForScope(scope, function, args[0].string_value()));

  if (g_scheduler->verbose_logging())
    g_scheduler->Log("Defining config", label.GetUserVisibleName(true));

  // Create the new config.
  std::unique_ptr<Config> config = std::make_unique<Config>(
      scope->settings(), label, scope->build_dependency_files());
  config->set_defined_from(function);
  if (!Visibility::FillItemVisibility(config.get(), scope, err))
    return Value();

  // Fill the flags and such.
  const SourceDir& input_dir = scope->GetSourceDir();
  ConfigValuesGenerator gen(&config->own_values(), scope, input_dir, err);
  gen.Run();
  if (err->has_error())
    return Value();

  // Read sub-configs.
  const Value* configs_value = scope->GetValue(variables::kConfigs, true);
  if (configs_value) {
    ExtractListOfUniqueLabels(*configs_value, scope->GetSourceDir(),
                              ToolchainLabelForScope(scope), &config->configs(),
                              err);
  }
  if (err->has_error())
    return Value();

  // Save the generated item.
  Scope::ItemVector* collector = scope->GetItemCollector();
  if (!collector) {
    *err = Err(function, "Can't define a config in this context.");
    return Value();
  }
  collector->push_back(std::move(config));

  return Value();
}

// declare_args ----------------------------------------------------------------

const char kDeclareArgs[] = "declare_args";
const char kDeclareArgs_HelpShort[] = "declare_args: Declare build arguments.";
const char kDeclareArgs_Help[] =
    R"(declare_args: Declare build arguments.

  Introduces the given arguments into the current scope. If they are not
  specified on the command line or in a toolchain's arguments, the default
  values given in the declare_args block will be used. However, these defaults
  will not override command-line values.

  See also "gn help buildargs" for an overview.

  The precise behavior of declare args is:

   1. The declare_args() block executes. Any variable defined in the enclosing
      scope is available for reading, but any variable defined earlier in
      the current scope is not (since the overrides haven't been applied yet).

   2. At the end of executing the block, any variables set within that scope
      are saved globally as build arguments, with their current values being
      saved as the "default value" for that argument.

   3. User-defined overrides are applied. Anything set in "gn args" now
      overrides any default values. The resulting set of variables is promoted
      to be readable from the following code in the file.

  This has some ramifications that may not be obvious:

    - You should not perform difficult work inside a declare_args block since
      this only sets a default value that may be discarded. In particular,
      don't use the result of exec_script() to set the default value. If you
      want to have a script-defined default, set some default "undefined" value
      like [], "", or -1, and after the declare_args block, call exec_script if
      the value is unset by the user.

    - Because you cannot read the value of a variable defined in the same
      block, if you need to make the default value of one arg depend
      on the possibly-overridden value of another, write two separate
      declare_args() blocks:

        declare_args() {
          enable_foo = true
        }
        declare_args() {
          # Bar defaults to same user-overridden state as foo.
          enable_bar = enable_foo
        }

Example

  declare_args() {
    enable_teleporter = true
    enable_doom_melon = false
  }

  If you want to override the (default disabled) Doom Melon:
    gn --args="enable_doom_melon=true enable_teleporter=true"
  This also sets the teleporter, but it's already defaulted to on so it will
  have no effect.
)";

Value RunDeclareArgs(Scope* scope,
                     const FunctionCallNode* function,
                     const std::vector<Value>& args,
                     BlockNode* block,
                     Err* err) {
  NonNestableBlock non_nestable(scope, function, "declare_args");
  if (!non_nestable.Enter(err))
    return Value();

  Scope block_scope(scope);
  block_scope.SetProperty(&kInDeclareArgsKey, &block_scope);
  block->Execute(&block_scope, err);
  if (err->has_error())
    return Value();

  // Pass the values from our scope into the Args object for adding to the
  // scope with the proper values (taking into account the defaults given in
  // the block_scope, and arguments passed into the build).
  Scope::KeyValueMap values;
  block_scope.GetCurrentScopeValues(&values);
  scope->settings()->build_settings()->build_args().DeclareArgs(values, scope,
                                                                err);
  return Value();
}

// defined ---------------------------------------------------------------------

const char kDefined[] = "defined";
const char kDefined_HelpShort[] =
    "defined: Returns whether an identifier is defined.";
const char kDefined_Help[] =
    R"(defined: Returns whether an identifier is defined.

  Returns true if the given argument is defined. This is most useful in
  templates to assert that the caller set things up properly.

  You can pass an identifier:
    defined(foo)
  which will return true or false depending on whether foo is defined in the
  current scope.

  You can also check a named scope:
    defined(foo.bar)
  which will return true or false depending on whether bar is defined in the
  named scope foo. It will throw an error if foo is not defined or is not a
  scope.

Example

  template("mytemplate") {
    # To help users call this template properly...
    assert(defined(invoker.sources), "Sources must be defined")

    # If we want to accept an optional "values" argument, we don't
    # want to dereference something that may not be defined.
    if (defined(invoker.values)) {
      values = invoker.values
    } else {
      values = "some default value"
    }
  }
)";

Value RunDefined(Scope* scope,
                 const FunctionCallNode* function,
                 const ListNode* args_list,
                 Err* err) {
  const auto& args_vector = args_list->contents();
  if (args_vector.size() != 1) {
    *err = Err(function, "Wrong number of arguments to defined().",
               "Expecting exactly one.");
    return Value();
  }

  const IdentifierNode* identifier = args_vector[0]->AsIdentifier();
  if (identifier) {
    // Passed an identifier "defined(foo)".
    if (scope->GetValue(identifier->value().value()))
      return Value(function, true);
    return Value(function, false);
  }

  const AccessorNode* accessor = args_vector[0]->AsAccessor();
  if (accessor) {
    // Passed an accessor "defined(foo.bar)".
    if (accessor->member()) {
      // The base of the accessor must be a scope if it's defined.
      const Value* base = scope->GetValue(accessor->base().value());
      if (!base) {
        *err = Err(accessor, "Undefined identifier");
        return Value();
      }
      if (!base->VerifyTypeIs(Value::SCOPE, err))
        return Value();

      // Check the member inside the scope to see if its defined.
      if (base->scope_value()->GetValue(accessor->member()->value().value()))
        return Value(function, true);
      return Value(function, false);
    }
  }

  // Argument is invalid.
  *err = Err(function, "Bad thing passed to defined().",
             "It should be of the form defined(foo) or defined(foo.bar).");
  return Value();
}

// getenv ----------------------------------------------------------------------

const char kGetEnv[] = "getenv";
const char kGetEnv_HelpShort[] = "getenv: Get an environment variable.";
const char kGetEnv_Help[] =
    R"(getenv: Get an environment variable.

  value = getenv(env_var_name)

  Returns the value of the given environment variable. If the value is not
  found, it will try to look up the variable with the "opposite" case (based on
  the case of the first letter of the variable), but is otherwise
  case-sensitive.

  If the environment variable is not found, the empty string will be returned.
  Note: it might be nice to extend this if we had the concept of "none" in the
  language to indicate lookup failure.

Example

  home_dir = getenv("HOME")
)";

Value RunGetEnv(Scope* scope,
                const FunctionCallNode* function,
                const std::vector<Value>& args,
                Err* err) {
  if (!EnsureSingleStringArg(function, args, err))
    return Value();

  std::unique_ptr<base::Environment> env(base::Environment::Create());

  std::string result;
  if (!env->GetVar(args[0].string_value().c_str(), &result))
    return Value(function, "");  // Not found, return empty string.
  return Value(function, result);
}

// import ----------------------------------------------------------------------

const char kImport[] = "import";
const char kImport_HelpShort[] =
    "import: Import a file into the current scope.";
const char kImport_Help[] =
    R"(import: Import a file into the current scope.

  The import command loads the rules and variables resulting from executing the
  given file into the current scope.

  By convention, imported files are named with a .gni extension.

  An import is different than a C++ "include". The imported file is executed in
  a standalone environment from the caller of the import command. The results
  of this execution are cached for other files that import the same .gni file.

  Note that you can not import a BUILD.gn file that's otherwise used in the
  build. Files must either be imported or implicitly loaded as a result of deps
  rules, but not both.

  The imported file's scope will be merged with the scope at the point import
  was called. If there is a conflict (both the current scope and the imported
  file define some variable or rule with the same name but different value), a
  runtime error will be thrown. Therefore, it's good practice to minimize the
  stuff that an imported file defines.

  Variables and templates beginning with an underscore '_' are considered
  private and will not be imported. Imported files can use such variables for
  internal computation without affecting other files.

Examples

  import("//build/rules/idl_compilation_rule.gni")

  # Looks in the current directory.
  import("my_vars.gni")
)";

Value RunImport(Scope* scope,
                const FunctionCallNode* function,
                const std::vector<Value>& args,
                Err* err) {
  if (!EnsureSingleStringArg(function, args, err))
    return Value();

  const SourceDir& input_dir = scope->GetSourceDir();
  SourceFile import_file = input_dir.ResolveRelativeFile(
      args[0], err, scope->settings()->build_settings()->root_path_utf8());
  scope->AddBuildDependencyFile(import_file);
  if (!err->has_error()) {
    scope->settings()->import_manager().DoImport(import_file, function, scope,
                                                 err);
  }
  return Value();
}

// not_needed -----------------------------------------------------------------

const char kNotNeeded[] = "not_needed";
const char kNotNeeded_HelpShort[] =
    "not_needed: Mark variables from scope as not needed.";
const char kNotNeeded_Help[] =
    R"(not_needed: Mark variables from scope as not needed.

  not_needed(variable_list_or_star, variable_to_ignore_list = [])
  not_needed(from_scope, variable_list_or_star,
             variable_to_ignore_list = [])

  Mark the variables in the current or given scope as not needed, which means
  you will not get an error about unused variables for these. The
  variable_to_ignore_list allows excluding variables from "all matches" if
  variable_list_or_star is "*".

Example

  not_needed("*", [ "config" ])
  not_needed([ "data_deps", "deps" ])
  not_needed(invoker, "*", [ "config" ])
  not_needed(invoker, [ "data_deps", "deps" ])
)";

Value RunNotNeeded(Scope* scope,
                   const FunctionCallNode* function,
                   const ListNode* args_list,
                   Err* err) {
  const auto& args_vector = args_list->contents();
  if (args_vector.size() < 1 || args_vector.size() > 3) {
    *err = Err(function, "Wrong number of arguments.",
               "Expecting one, two or three arguments.");
    return Value();
  }
  auto args_cur = args_vector.begin();

  Value* value = nullptr;  // Value to use, may point to result_value.
  Value result_value;      // Storage for the "evaluate" case.
  Value scope_value;       // Storage for an evaluated scope.
  const IdentifierNode* identifier = (*args_cur)->AsIdentifier();
  if (identifier) {
    // Optimize the common case where the input scope is an identifier. This
    // prevents a copy of a potentially large Scope object.
    value = scope->GetMutableValue(identifier->value().value(),
                                   Scope::SEARCH_NESTED, true);
    if (!value) {
      *err = Err(identifier, "Undefined identifier.");
      return Value();
    }
  } else {
    // Non-optimized case, just evaluate the argument.
    result_value = (*args_cur)->Execute(scope, err);
    if (err->has_error())
      return Value();
    value = &result_value;
  }
  args_cur++;

  // Extract the source scope if different from current one.
  Scope* source = scope;
  if (value->type() == Value::SCOPE) {
    if (args_cur == args_vector.end()) {
      *err = Err(
          function, "Wrong number of arguments.",
          "The first argument is a scope, expecting two or three arguments.");
      return Value();
    }
    // Copy the scope value if it will be overridden.
    if (value == &result_value) {
      scope_value = Value(nullptr, value->scope_value()->MakeClosure());
      source = scope_value.scope_value();
    } else {
      source = value->scope_value();
    }
    result_value = (*args_cur)->Execute(scope, err);
    if (err->has_error())
      return Value();
    value = &result_value;
    args_cur++;
  } else if (args_vector.size() > 2) {
    *err = Err(
        function, "Wrong number of arguments.",
        "The first argument is not a scope, expecting one or two arguments.");
    return Value();
  }

  // Extract the exclusion list if defined.
  Value exclusion_value;
  std::set<std::string> exclusion_set;
  if (args_cur != args_vector.end()) {
    exclusion_value = (*args_cur)->Execute(source, err);
    if (err->has_error())
      return Value();

    if (exclusion_value.type() != Value::LIST) {
      *err = Err(exclusion_value, "Not a valid list of variables to exclude.",
                 "Expecting a list of strings.");
      return Value();
    }

    for (const Value& cur : exclusion_value.list_value()) {
      if (!cur.VerifyTypeIs(Value::STRING, err))
        return Value();

      exclusion_set.insert(cur.string_value());
    }
  }

  if (value->type() == Value::STRING) {
    if (value->string_value() == "*") {
      source->MarkAllUsed(exclusion_set);
      return Value();
    }
  } else if (value->type() == Value::LIST) {
    if (exclusion_value.type() != Value::NONE) {
      *err = Err(exclusion_value, "Not supported with a variable list.",
                 "Exclusion list can only be used with the string \"*\".");
      return Value();
    }
    for (const Value& cur : value->list_value()) {
      if (!cur.VerifyTypeIs(Value::STRING, err))
        return Value();
      if (!source->GetValue(cur.string_value(), true)) {
        *err = Err(cur, "Undefined identifier");
        return Value();
      }
    }
    return Value();
  }

  // Not the right type of argument.
  *err = Err(*value, "Not a valid list of variables.",
             "Expecting either the string \"*\" or a list of strings.");
  return Value();
}

// set_sources_assignment_filter -----------------------------------------------

const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter";
const char kSetSourcesAssignmentFilter_HelpShort[] =
    "set_sources_assignment_filter: Set a pattern to filter source files.";
const char kSetSourcesAssignmentFilter_Help[] =
    R"(set_sources_assignment_filter: Set a pattern to filter source files.

  The sources assignment filter is a list of patterns that remove files from
  the list implicitly whenever the "sources" variable is assigned to. This will
  do nothing for non-lists.

  This is intended to be used to globally filter out files with
  platform-specific naming schemes when they don't apply, for example you may
  want to filter out all "*_win.cc" files on non-Windows platforms.

  Typically this will be called once in the master build config script to set
  up the filter for the current platform. Subsequent calls will overwrite the
  previous values.

  If you want to bypass the filter and add a file even if it might be filtered
  out, call set_sources_assignment_filter([]) to clear the list of filters.
  This will apply until the current scope exits

How to use patterns

  File patterns are VERY limited regular expressions. They must match the
  entire input string to be counted as a match. In regular expression parlance,
  there is an implicit "^...$" surrounding your input. If you want to match a
  substring, you need to use wildcards at the beginning and end.

  There are only two special tokens understood by the pattern matcher.
  Everything else is a literal.

   - "*" Matches zero or more of any character. It does not depend on the
     preceding character (in regular expression parlance it is equivalent to
     ".*").

   - "\b" Matches a path boundary. This will match the beginning or end of a
     string, or a slash.

Pattern examples

  "*asdf*"
      Matches a string containing "asdf" anywhere.

  "asdf"
      Matches only the exact string "asdf".

  "*.cc"
      Matches strings ending in the literal ".cc".

  "\bwin/*"
      Matches "win/foo" and "foo/win/bar.cc" but not "iwin/foo".

Sources assignment example

  # Filter out all _win files.
  set_sources_assignment_filter([ "*_win.cc", "*_win.h" ])
  sources = [ "a.cc", "b_win.cc" ]
  print(sources)
  # Will print [ "a.cc" ]. b_win one was filtered out.
)";

Value RunSetSourcesAssignmentFilter(Scope* scope,
                                    const FunctionCallNode* function,
                                    const std::vector<Value>& args,
                                    Err* err) {
  if (args.size() != 1) {
    *err = Err(function, "set_sources_assignment_filter takes one argument.");
  } else {
    std::unique_ptr<PatternList> f = std::make_unique<PatternList>();
    f->SetFromValue(args[0], err);
    if (!err->has_error())
      scope->set_sources_assignment_filter(std::move(f));
  }
  return Value();
}

// pool ------------------------------------------------------------------------

const char kPool[] = "pool";
const char kPool_HelpShort[] = "pool: Defines a pool object.";
const char kPool_Help[] =
    R"*(pool: Defines a pool object.

  Pool objects can be applied to a tool to limit the parallelism of the
  build. This object has a single property "depth" corresponding to
  the number of tasks that may run simultaneously.

  As the file containing the pool definition may be executed in the
  context of more than one toolchain it is recommended to specify an
  explicit toolchain when defining and referencing a pool.

  A pool named "console" defined in the root build file represents Ninja's
  console pool. Targets using this pool will have access to the console's
  stdin and stdout, and output will not be buffered. This special pool must
  have a depth of 1. Pools not defined in the root must not be named "console".
  The console pool can only be defined for the default toolchain.
  Refer to the Ninja documentation on the console pool for more info.

  A pool is referenced by its label just like a target.

Variables

  depth*
  * = required

Example

  if (current_toolchain == default_toolchain) {
    pool("link_pool") {
      depth = 1
    }
  }

  toolchain("toolchain") {
    tool("link") {
      command = "..."
      pool = ":link_pool($default_toolchain)")
    }
  }
)*";

const char kDepth[] = "depth";

Value RunPool(const FunctionCallNode* function,
              const std::vector<Value>& args,
              Scope* scope,
              Err* err) {
  NonNestableBlock non_nestable(scope, function, "pool");
  if (!non_nestable.Enter(err))
    return Value();

  if (!EnsureSingleStringArg(function, args, err) ||
      !EnsureNotProcessingImport(function, scope, err))
    return Value();

  Label label(MakeLabelForScope(scope, function, args[0].string_value()));

  if (g_scheduler->verbose_logging())
    g_scheduler->Log("Defining pool", label.GetUserVisibleName(true));

  // Get the pool depth. It is an error to define a pool without a depth,
  // so check first for the presence of the value.
  const Value* depth = scope->GetValue(kDepth, true);
  if (!depth) {
    *err = Err(function, "Can't define a pool without depth.");
    return Value();
  }

  if (!depth->VerifyTypeIs(Value::INTEGER, err))
    return Value();

  if (depth->int_value() < 0) {
    *err = Err(*depth, "depth must be positive or 0.");
    return Value();
  }

  // Create the new pool.
  std::unique_ptr<Pool> pool = std::make_unique<Pool>(
      scope->settings(), label, scope->build_dependency_files());

  if (label.name() == "console") {
    const Settings* settings = scope->settings();
    if (!settings->is_default()) {
      *err = Err(
          function,
          "\"console\" pool must be defined only in the default toolchain.");
      return Value();
    }
    if (label.dir() != settings->build_settings()->root_target_label().dir()) {
      *err = Err(function, "\"console\" pool must be defined in the root //.");
      return Value();
    }
    if (depth->int_value() != 1) {
      *err = Err(*depth, "\"console\" pool must have depth 1.");
      return Value();
    }
  }
  pool->set_depth(depth->int_value());

  // Save the generated item.
  Scope::ItemVector* collector = scope->GetItemCollector();
  if (!collector) {
    *err = Err(function, "Can't define a pool in this context.");
    return Value();
  }
  collector->push_back(std::move(pool));

  return Value();
}

// print -----------------------------------------------------------------------

const char kPrint[] = "print";
const char kPrint_HelpShort[] = "print: Prints to the console.";
const char kPrint_Help[] =
    R"(print: Prints to the console.

  Prints all arguments to the console separated by spaces. A newline is
  automatically appended to the end.

  This function is intended for debugging. Note that build files are run in
  parallel so you may get interleaved prints. A buildfile may also be executed
  more than once in parallel in the context of different toolchains so the
  prints from one file may be duplicated or
  interleaved with itself.

Examples

  print("Hello world")

  print(sources, deps)
)";

Value RunPrint(Scope* scope,
               const FunctionCallNode* function,
               const std::vector<Value>& args,
               Err* err) {
  std::string output;
  for (size_t i = 0; i < args.size(); i++) {
    if (i != 0)
      output.push_back(' ');
    output.append(args[i].ToString(false));
  }
  output.push_back('\n');

  const BuildSettings::PrintCallback& cb =
      scope->settings()->build_settings()->print_callback();
  if (cb.is_null()) {
    printf("%s", output.c_str());
    fflush(stdout);
  } else
    cb.Run(output);

  return Value();
}

// split_list ------------------------------------------------------------------

const char kSplitList[] = "split_list";
const char kSplitList_HelpShort[] =
    "split_list: Splits a list into N different sub-lists.";
const char kSplitList_Help[] =
    R"(split_list: Splits a list into N different sub-lists.

  result = split_list(input, n)

  Given a list and a number N, splits the list into N sub-lists of
  approximately equal size. The return value is a list of the sub-lists. The
  result will always be a list of size N. If N is greater than the number of
  elements in the input, it will be padded with empty lists.

  The expected use is to divide source files into smaller uniform chunks.

Example

  The code:
    mylist = [1, 2, 3, 4, 5, 6]
    print(split_list(mylist, 3))

  Will print:
    [[1, 2], [3, 4], [5, 6]
)";
Value RunSplitList(Scope* scope,
                   const FunctionCallNode* function,
                   const ListNode* args_list,
                   Err* err) {
  const auto& args_vector = args_list->contents();
  if (args_vector.size() != 2) {
    *err = Err(function, "Wrong number of arguments to split_list().",
               "Expecting exactly two.");
    return Value();
  }

  ParseNodeValueAdapter list_adapter;
  if (!list_adapter.InitForType(scope, args_vector[0].get(), Value::LIST, err))
    return Value();
  const std::vector<Value>& input = list_adapter.get().list_value();

  ParseNodeValueAdapter count_adapter;
  if (!count_adapter.InitForType(scope, args_vector[1].get(), Value::INTEGER,
                                 err))
    return Value();
  int64_t count = count_adapter.get().int_value();
  if (count <= 0) {
    *err = Err(function, "Requested result size is not positive.");
    return Value();
  }

  Value result(function, Value::LIST);
  result.list_value().resize(count);

  // Every result list gets at least this many items in it.
  int64_t min_items_per_list = static_cast<int64_t>(input.size()) / count;

  // This many result lists get an extra item which is the remainder from above.
  int64_t extra_items = static_cast<int64_t>(input.size()) % count;

  // Allocate all lists that have a remainder assigned to them (max items).
  int64_t max_items_per_list = min_items_per_list + 1;
  auto last_item_end = input.begin();
  for (int64_t i = 0; i < extra_items; i++) {
    result.list_value()[i] = Value(function, Value::LIST);

    auto begin_add = last_item_end;
    last_item_end += max_items_per_list;
    result.list_value()[i].list_value().assign(begin_add, last_item_end);
  }

  // Allocate all smaller items that don't have a remainder.
  for (int64_t i = extra_items; i < count; i++) {
    result.list_value()[i] = Value(function, Value::LIST);

    auto begin_add = last_item_end;
    last_item_end += min_items_per_list;
    result.list_value()[i].list_value().assign(begin_add, last_item_end);
  }

  return result;
}

// string_replace --------------------------------------------------------------

const char kStringReplace[] = "string_replace";
const char kStringReplace_HelpShort[] =
    "string_replace: Replaces substring in the given string.";
const char kStringReplace_Help[] =
    R"(string_replace: Replaces substring in the given string.

  result = string_replace(str, old, new[, max])

  Returns a copy of the string str in which the occurrences of old have been
  replaced with new, optionally restricting the number of replacements. The
  replacement is performed sequentially, so if new contains old, it won't be
  replaced.

Example

  The code:
    mystr = "Hello, world!"
    print(string_replace(mystr, "world", "GN"))

  Will print:
    Hello, GN!
)";

Value RunStringReplace(Scope* scope,
                       const FunctionCallNode* function,
                       const std::vector<Value>& args,
                       Err* err) {
  if (args.size() < 3 || args.size() > 4) {
    *err = Err(function, "Wrong number of arguments to string_replace().");
    return Value();
  }

  if (!args[0].VerifyTypeIs(Value::STRING, err))
    return Value();
  const std::string str = args[0].string_value();

  if (!args[1].VerifyTypeIs(Value::STRING, err))
    return Value();
  const std::string& old = args[1].string_value();

  if (!args[2].VerifyTypeIs(Value::STRING, err))
    return Value();
  const std::string& new_ = args[2].string_value();

  int64_t max = INT64_MAX;
  if (args.size() > 3) {
    if (!args[3].VerifyTypeIs(Value::INTEGER, err))
      return Value();
    max = args[3].int_value();
    if (max <= 0) {
      *err = Err(function, "Requested number of replacements is not positive.");
      return Value();
    }
  }

  int64_t n = 0;
  std::string val(str);
  size_t start_pos = 0;
  while((start_pos = val.find(old, start_pos)) != std::string::npos) {
    val.replace(start_pos, old.length(), new_);
    start_pos += new_.length();
    if (++n >= max)
      break;
  }
  return Value(function, std::move(val));
}

// -----------------------------------------------------------------------------

FunctionInfo::FunctionInfo()
    : self_evaluating_args_runner(nullptr),
      generic_block_runner(nullptr),
      executed_block_runner(nullptr),
      no_block_runner(nullptr),
      help_short(nullptr),
      help(nullptr),
      is_target(false) {}

FunctionInfo::FunctionInfo(SelfEvaluatingArgsFunction seaf,
                           const char* in_help_short,
                           const char* in_help,
                           bool in_is_target)
    : self_evaluating_args_runner(seaf),
      generic_block_runner(nullptr),
      executed_block_runner(nullptr),
      no_block_runner(nullptr),
      help_short(in_help_short),
      help(in_help),
      is_target(in_is_target) {}

FunctionInfo::FunctionInfo(GenericBlockFunction gbf,
                           const char* in_help_short,
                           const char* in_help,
                           bool in_is_target)
    : self_evaluating_args_runner(nullptr),
      generic_block_runner(gbf),
      executed_block_runner(nullptr),
      no_block_runner(nullptr),
      help_short(in_help_short),
      help(in_help),
      is_target(in_is_target) {}

FunctionInfo::FunctionInfo(ExecutedBlockFunction ebf,
                           const char* in_help_short,
                           const char* in_help,
                           bool in_is_target)
    : self_evaluating_args_runner(nullptr),
      generic_block_runner(nullptr),
      executed_block_runner(ebf),
      no_block_runner(nullptr),
      help_short(in_help_short),
      help(in_help),
      is_target(in_is_target) {}

FunctionInfo::FunctionInfo(NoBlockFunction nbf,
                           const char* in_help_short,
                           const char* in_help,
                           bool in_is_target)
    : self_evaluating_args_runner(nullptr),
      generic_block_runner(nullptr),
      executed_block_runner(nullptr),
      no_block_runner(nbf),
      help_short(in_help_short),
      help(in_help),
      is_target(in_is_target) {}

// Setup the function map via a static initializer. We use this because it
// avoids race conditions without having to do some global setup function or
// locking-heavy singleton checks at runtime. In practice, we always need this
// before we can do anything interesting, so it's OK to wait for the
// initializer.
struct FunctionInfoInitializer {
  FunctionInfoMap map;

  FunctionInfoInitializer() {
#define INSERT_FUNCTION(command, is_target)                             \
  map[k##command] = FunctionInfo(&Run##command, k##command##_HelpShort, \
                                 k##command##_Help, is_target);

    INSERT_FUNCTION(Action, true)
    INSERT_FUNCTION(ActionForEach, true)
    INSERT_FUNCTION(BundleData, true)
    INSERT_FUNCTION(CreateBundle, true)
    INSERT_FUNCTION(Copy, true)
    INSERT_FUNCTION(Executable, true)
    INSERT_FUNCTION(Group, true)
    INSERT_FUNCTION(LoadableModule, true)
    INSERT_FUNCTION(SharedLibrary, true)
    INSERT_FUNCTION(SourceSet, true)
    INSERT_FUNCTION(StaticLibrary, true)
    INSERT_FUNCTION(Target, true)
    INSERT_FUNCTION(GeneratedFile, true)

    INSERT_FUNCTION(Assert, false)
    INSERT_FUNCTION(Config, false)
    INSERT_FUNCTION(DeclareArgs, false)
    INSERT_FUNCTION(Defined, false)
    INSERT_FUNCTION(ExecScript, false)
    INSERT_FUNCTION(ForEach, false)
    INSERT_FUNCTION(ForwardVariablesFrom, false)
    INSERT_FUNCTION(GetEnv, false)
    INSERT_FUNCTION(GetLabelInfo, false)
    INSERT_FUNCTION(GetPathInfo, false)
    INSERT_FUNCTION(GetTargetOutputs, false)
    INSERT_FUNCTION(Import, false)
    INSERT_FUNCTION(NotNeeded, false)
    INSERT_FUNCTION(Pool, false)
    INSERT_FUNCTION(Print, false)
    INSERT_FUNCTION(ProcessFileTemplate, false)
    INSERT_FUNCTION(ReadFile, false)
    INSERT_FUNCTION(RebasePath, false)
    INSERT_FUNCTION(SetDefaults, false)
    INSERT_FUNCTION(SetDefaultToolchain, false)
    INSERT_FUNCTION(SetSourcesAssignmentFilter, false)
    INSERT_FUNCTION(SplitList, false)
    INSERT_FUNCTION(StringReplace, false)
    INSERT_FUNCTION(Template, false)
    INSERT_FUNCTION(Tool, false)
    INSERT_FUNCTION(Toolchain, false)
    INSERT_FUNCTION(WriteFile, false)

#undef INSERT_FUNCTION
  }
};
const FunctionInfoInitializer function_info;

const FunctionInfoMap& GetFunctions() {
  return function_info.map;
}

Value RunFunction(Scope* scope,
                  const FunctionCallNode* function,
                  const ListNode* args_list,
                  BlockNode* block,
                  Err* err) {
  const Token& name = function->function();

  std::string template_name = function->function().value().as_string();
  const Template* templ = scope->GetTemplate(template_name);
  if (templ) {
    Value args = args_list->Execute(scope, err);
    if (err->has_error())
      return Value();
    return templ->Invoke(scope, function, template_name, args.list_value(),
                         block, err);
  }

  // No template matching this, check for a built-in function.
  const FunctionInfoMap& function_map = GetFunctions();
  FunctionInfoMap::const_iterator found_function =
      function_map.find(name.value());
  if (found_function == function_map.end()) {
    *err = Err(name, "Unknown function.");
    return Value();
  }

  if (found_function->second.self_evaluating_args_runner) {
    // Self evaluating args functions are special weird built-ins like foreach.
    // Rather than force them all to check that they have a block or no block
    // and risk bugs for new additions, check a whitelist here.
    if (found_function->second.self_evaluating_args_runner != &RunForEach) {
      if (!VerifyNoBlockForFunctionCall(function, block, err))
        return Value();
    }
    return found_function->second.self_evaluating_args_runner(scope, function,
                                                              args_list, err);
  }

  // All other function types take a pre-executed set of args.
  Value args = args_list->Execute(scope, err);
  if (err->has_error())
    return Value();

  if (found_function->second.generic_block_runner) {
    if (!block) {
      FillNeedsBlockError(function, err);
      return Value();
    }
    return found_function->second.generic_block_runner(
        scope, function, args.list_value(), block, err);
  }

  if (found_function->second.executed_block_runner) {
    if (!block) {
      FillNeedsBlockError(function, err);
      return Value();
    }

    Scope block_scope(scope);
    block->Execute(&block_scope, err);
    if (err->has_error())
      return Value();

    Value result = found_function->second.executed_block_runner(
        function, args.list_value(), &block_scope, err);
    if (err->has_error())
      return Value();

    if (!block_scope.CheckForUnusedVars(err))
      return Value();
    return result;
  }

  // Otherwise it's a no-block function.
  if (!VerifyNoBlockForFunctionCall(function, block, err))
    return Value();
  return found_function->second.no_block_runner(scope, function,
                                                args.list_value(), err);
}

}  // namespace functions
