|  | // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_ | 
|  | #define TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  |  | 
|  | #include <ostream> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "tools/gn/config.h" | 
|  | #include "tools/gn/config_values.h" | 
|  | #include "tools/gn/target.h" | 
|  |  | 
|  | struct EscapeOptions; | 
|  |  | 
|  | // Provides a way to iterate through all ConfigValues applying to a given | 
|  | // target. This is more complicated than normal because the target has a list | 
|  | // of configs applying to it, and also config values on the target itself. | 
|  | // | 
|  | // This iterator allows one to iterate through all of these in a defined order | 
|  | // in one convenient loop. The order is defined to be the ConfigValues on the | 
|  | // target itself first, then the applying configs, in order. | 
|  | // | 
|  | // Example: | 
|  | //   for (ConfigValueIterator iter(target); !iter.done(); iter.Next()) | 
|  | //     DoSomething(iter.cur()); | 
|  | class ConfigValuesIterator { | 
|  | public: | 
|  | explicit ConfigValuesIterator(const Target* target) | 
|  | : target_(target), cur_index_(-1) {} | 
|  |  | 
|  | bool done() const { | 
|  | return cur_index_ >= static_cast<int>(target_->configs().size()); | 
|  | } | 
|  |  | 
|  | const ConfigValues& cur() const { | 
|  | if (cur_index_ == -1) | 
|  | return target_->config_values(); | 
|  | return target_->configs()[cur_index_].ptr->resolved_values(); | 
|  | } | 
|  |  | 
|  | // Returns the origin of who added this config, if any. This will always be | 
|  | // null for the config values of a target itself. | 
|  | const ParseNode* origin() const { | 
|  | if (cur_index_ == -1) | 
|  | return nullptr; | 
|  | return target_->configs()[cur_index_].origin; | 
|  | } | 
|  |  | 
|  | void Next() { cur_index_++; } | 
|  |  | 
|  | // Returns the config holding the current config values, or NULL for those | 
|  | // config values associated with the target itself. | 
|  | const Config* GetCurrentConfig() const { | 
|  | if (cur_index_ == -1) | 
|  | return nullptr; | 
|  | return target_->configs()[cur_index_].ptr; | 
|  | } | 
|  |  | 
|  | private: | 
|  | const Target* target_; | 
|  |  | 
|  | // Represents an index into the target_'s configs() or, when -1, the config | 
|  | // values on the target itself. | 
|  | int cur_index_; | 
|  | }; | 
|  |  | 
|  | template <typename T, class Writer> | 
|  | inline void ConfigValuesToStream(const ConfigValues& values, | 
|  | const std::vector<T>& (ConfigValues::*getter)() | 
|  | const, | 
|  | const Writer& writer, | 
|  | std::ostream& out) { | 
|  | const std::vector<T>& v = (values.*getter)(); | 
|  | for (size_t i = 0; i < v.size(); i++) | 
|  | writer(v[i], out); | 
|  | } | 
|  |  | 
|  | // Writes a given config value that applies to a given target. This collects | 
|  | // all values from the target itself and all configs that apply, and writes | 
|  | // then in order. | 
|  | template <typename T, class Writer> | 
|  | inline void RecursiveTargetConfigToStream( | 
|  | const Target* target, | 
|  | const std::vector<T>& (ConfigValues::*getter)() const, | 
|  | const Writer& writer, | 
|  | std::ostream& out) { | 
|  | for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) | 
|  | ConfigValuesToStream(iter.cur(), getter, writer, out); | 
|  | } | 
|  |  | 
|  | // Writes the values out as strings with no transformation. | 
|  | void RecursiveTargetConfigStringsToStream( | 
|  | const Target* target, | 
|  | const std::vector<std::string>& (ConfigValues::*getter)() const, | 
|  | const EscapeOptions& escape_options, | 
|  | std::ostream& out); | 
|  |  | 
|  | #endif  // TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_ |