• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     // If the target doesn't have its own config_values()
35     if (!target->has_config_values()) {
36       cur_index_ = 0;
37     }
38   }
39 
done()40   bool done() const {
41     return cur_index_ >= static_cast<int>(target_->configs().size());
42   }
43 
cur()44   const ConfigValues& cur() const {
45     if (cur_index_ == -1)
46       return target_->config_values();
47     return target_->configs()[cur_index_].ptr->resolved_values();
48   }
49 
50   // Returns the origin of who added this config, if any. This will always be
51   // null for the config values of a target itself.
origin()52   const ParseNode* origin() const {
53     if (cur_index_ == -1)
54       return nullptr;
55     return target_->configs()[cur_index_].origin;
56   }
57 
Next()58   void Next() { cur_index_++; }
59 
60   // Returns the config holding the current config values, or NULL for those
61   // config values associated with the target itself.
GetCurrentConfig()62   const Config* GetCurrentConfig() const {
63     if (cur_index_ == -1)
64       return nullptr;
65     return target_->configs()[cur_index_].ptr;
66   }
67 
68  private:
69   const Target* target_;
70 
71   // Represents an index into the target_'s configs() or, when -1, the config
72   // values on the target itself.
73   int cur_index_ = -1;
74 };
75 
76 enum RecursiveWriterConfig {
77   kRecursiveWriterKeepDuplicates,
78   kRecursiveWriterSkipDuplicates,
79 };
80 
81 // Writes a given config value that applies to a given target. This collects
82 // all values from the target itself and all configs that apply, and writes
83 // then in order.
84 template <typename T, class Writer>
RecursiveTargetConfigToStream(RecursiveWriterConfig config,const Target * target,const std::vector<T> & (ConfigValues::* getter)()const,const Writer & writer,std::ostream & out)85 inline void RecursiveTargetConfigToStream(
86     RecursiveWriterConfig config,
87     const Target* target,
88     const std::vector<T>& (ConfigValues::*getter)() const,
89     const Writer& writer,
90     std::ostream& out) {
91   std::set<T> seen;
92   for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
93     const std::vector<T>& values = ((iter.cur()).*getter)();
94     for (size_t i = 0; i < values.size(); i++) {
95       switch (config) {
96         case kRecursiveWriterKeepDuplicates:
97           writer(values[i], out);
98           break;
99 
100         case kRecursiveWriterSkipDuplicates:
101           if (seen.find(values[i]) == seen.end()) {
102             seen.insert(values[i]);
103             writer(values[i], out);
104           }
105       }
106     }
107   }
108 }
109 
110 // Writes the values out as strings with no transformation.
111 void RecursiveTargetConfigStringsToStream(
112     RecursiveWriterConfig config,
113     const Target* target,
114     const std::vector<std::string>& (ConfigValues::*getter)() const,
115     const EscapeOptions& escape_options,
116     std::ostream& out);
117 
118 #endif  // TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_
119