| // 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_ |