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