1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_ 6 #define TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_ 7 8 #include <ostream> 9 #include <string> 10 #include <vector> 11 12 #include "tools/gn/config.h" 13 #include "tools/gn/config_values.h" 14 #include "tools/gn/target.h" 15 16 struct EscapeOptions; 17 18 // Provides a way to iterate through all ConfigValues applying to a given 19 // target. This is more complicated than normal because the target has a list 20 // of configs applying to it, and also config values on the target itself. 21 // 22 // This iterator allows one to iterate through all of these in a defined order 23 // in one convenient loop. The order is defined to be the ConfigValues on the 24 // target itself first, then the applying configs, in order. 25 // 26 // Example: 27 // for (ConfigValueIterator iter(target); !iter.done(); iter.Next()) 28 // DoSomething(iter->cur()); 29 class ConfigValuesIterator { 30 public: 31 explicit ConfigValuesIterator(const Target* target) 32 : target_(target), 33 cur_index_(-1) { 34 } 35 36 bool done() const { 37 return cur_index_ >= static_cast<int>(target_->configs().size()); 38 } 39 40 const ConfigValues& cur() const { 41 if (cur_index_ == -1) 42 return target_->config_values(); 43 return target_->configs()[cur_index_].ptr->config_values(); 44 } 45 46 // Returns the origin of who added this config, if any. This will alwsya be 47 // null for the config values of a target itself. 48 const ParseNode* origin() const { 49 if (cur_index_ == -1) 50 return NULL; 51 return target_->configs()[cur_index_].origin; 52 } 53 54 void Next() { 55 cur_index_++; 56 } 57 58 // Returns the config holding the current config values, or NULL for those 59 // config values associated with the target itself. 60 const Config* GetCurrentConfig() const { 61 if (cur_index_ == -1) 62 return NULL; 63 return target_->configs()[cur_index_].ptr; 64 } 65 66 private: 67 const Target* target_; 68 69 // Represents an index into the target_'s configs() or, when -1, the config 70 // values on the target itself. 71 int cur_index_; 72 }; 73 74 template<typename T, class Writer> 75 inline void ConfigValuesToStream( 76 const ConfigValues& values, 77 const std::vector<T>& (ConfigValues::* getter)() const, 78 const Writer& writer, 79 std::ostream& out) { 80 const std::vector<T>& v = (values.*getter)(); 81 for (size_t i = 0; i < v.size(); i++) 82 writer(v[i], out); 83 }; 84 85 // Writes a given config value that applies to a given target. This collects 86 // all values from the target itself and all configs that apply, and writes 87 // then in order. 88 template<typename T, class Writer> 89 inline void RecursiveTargetConfigToStream( 90 const Target* target, 91 const std::vector<T>& (ConfigValues::* getter)() const, 92 const Writer& writer, 93 std::ostream& out) { 94 for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) 95 ConfigValuesToStream(iter.cur(), getter, writer, out); 96 } 97 98 // Writes the values out as strings with no transformation. 99 void RecursiveTargetConfigStringsToStream( 100 const Target* target, 101 const std::vector<std::string>& (ConfigValues::* getter)() const, 102 const EscapeOptions& escape_options, 103 std::ostream& out); 104 105 #endif // TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_ 106