Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / tools / gn / value_extractors.cc
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 #include "tools/gn/value_extractors.h"
6
7 #include "tools/gn/build_settings.h"
8 #include "tools/gn/err.h"
9 #include "tools/gn/label.h"
10 #include "tools/gn/source_dir.h"
11 #include "tools/gn/source_file.h"
12 #include "tools/gn/target.h"
13 #include "tools/gn/value.h"
14
15 namespace {
16
17 // Sets the error and returns false on failure.
18 template<typename T, class Converter>
19 bool ListValueExtractor(const Value& value,
20                         std::vector<T>* dest,
21                         Err* err,
22                         const Converter& converter) {
23   if (!value.VerifyTypeIs(Value::LIST, err))
24     return false;
25   const std::vector<Value>& input_list = value.list_value();
26   dest->resize(input_list.size());
27   for (size_t i = 0; i < input_list.size(); i++) {
28     if (!converter(input_list[i], &(*dest)[i], err))
29       return false;
30   }
31   return true;
32 }
33
34 // Like the above version but extracts to a UniqueVector and sets the error if
35 // there are duplicates.
36 template<typename T, class Converter>
37 bool ListValueUniqueExtractor(const Value& value,
38                               UniqueVector<T>* dest,
39                               Err* err,
40                               const Converter& converter) {
41   if (!value.VerifyTypeIs(Value::LIST, err))
42     return false;
43   const std::vector<Value>& input_list = value.list_value();
44
45   for (size_t i = 0; i < input_list.size(); i++) {
46     T new_one;
47     if (!converter(input_list[i], &new_one, err))
48       return false;
49     if (!dest->push_back(new_one)) {
50       // Already in the list, throw error.
51       *err = Err(input_list[i], "Duplicate item in list");
52       size_t previous_index = dest->IndexOf(new_one);
53       err->AppendSubErr(Err(input_list[previous_index],
54                             "This was the previous definition."));
55       return false;
56     }
57   }
58   return true;
59 }
60
61 // This extractor rejects files with system-absolute file paths. If we need
62 // that in the future, we'll have to add some flag to control this.
63 struct RelativeFileConverter {
64   RelativeFileConverter(const BuildSettings* build_settings_in,
65                         const SourceDir& current_dir_in)
66       : build_settings(build_settings_in),
67         current_dir(current_dir_in) {
68   }
69   bool operator()(const Value& v, SourceFile* out, Err* err) const {
70     if (!v.VerifyTypeIs(Value::STRING, err))
71       return false;
72     *out = current_dir.ResolveRelativeFile(v.string_value(),
73                                            build_settings->root_path_utf8());
74     if (out->is_system_absolute()) {
75       *err = Err(v, "System-absolute file path.",
76           "You can't list a system-absolute file path here. Please include "
77           "only files in\nthe source tree. Maybe you meant to begin with two "
78           "slashes to indicate an\nabsolute path in the source tree?");
79       return false;
80     }
81     return true;
82   }
83   const BuildSettings* build_settings;
84   const SourceDir& current_dir;
85 };
86
87 struct RelativeDirConverter {
88   RelativeDirConverter(const BuildSettings* build_settings_in,
89                        const SourceDir& current_dir_in)
90       : build_settings(build_settings_in),
91         current_dir(current_dir_in) {
92   }
93   bool operator()(const Value& v, SourceDir* out, Err* err) const {
94     if (!v.VerifyTypeIs(Value::STRING, err))
95       return false;
96     *out = current_dir.ResolveRelativeDir(v.string_value(),
97                                           build_settings->root_path_utf8());
98     return true;
99   }
100   const BuildSettings* build_settings;
101   const SourceDir& current_dir;
102 };
103
104 // Fills in a label.
105 template<typename T> struct LabelResolver {
106   LabelResolver(const SourceDir& current_dir_in,
107                 const Label& current_toolchain_in)
108       : current_dir(current_dir_in),
109         current_toolchain(current_toolchain_in) {}
110   bool operator()(const Value& v, Label* out, Err* err) const {
111     if (!v.VerifyTypeIs(Value::STRING, err))
112       return false;
113     *out = Label::Resolve(current_dir, current_toolchain, v, err);
114     return !err->has_error();
115   }
116   const SourceDir& current_dir;
117   const Label& current_toolchain;
118 };
119
120 // Fills the label part of a LabelPtrPair, leaving the pointer null.
121 template<typename T> struct LabelPtrResolver {
122   LabelPtrResolver(const SourceDir& current_dir_in,
123                    const Label& current_toolchain_in)
124       : current_dir(current_dir_in),
125         current_toolchain(current_toolchain_in) {}
126   bool operator()(const Value& v, LabelPtrPair<T>* out, Err* err) const {
127     if (!v.VerifyTypeIs(Value::STRING, err))
128       return false;
129     out->label = Label::Resolve(current_dir, current_toolchain, v, err);
130     out->origin = v.origin();
131     return !err->has_error();
132   }
133   const SourceDir& current_dir;
134   const Label& current_toolchain;
135 };
136
137 }  // namespace
138
139 bool ExtractListOfStringValues(const Value& value,
140                                std::vector<std::string>* dest,
141                                Err* err) {
142   if (!value.VerifyTypeIs(Value::LIST, err))
143     return false;
144   const std::vector<Value>& input_list = value.list_value();
145   dest->reserve(input_list.size());
146   for (size_t i = 0; i < input_list.size(); i++) {
147     if (!input_list[i].VerifyTypeIs(Value::STRING, err))
148       return false;
149     dest->push_back(input_list[i].string_value());
150   }
151   return true;
152 }
153
154 bool ExtractListOfRelativeFiles(const BuildSettings* build_settings,
155                                 const Value& value,
156                                 const SourceDir& current_dir,
157                                 std::vector<SourceFile>* files,
158                                 Err* err) {
159   return ListValueExtractor(value, files, err,
160                             RelativeFileConverter(build_settings, current_dir));
161 }
162
163 bool ExtractListOfRelativeDirs(const BuildSettings* build_settings,
164                                const Value& value,
165                                const SourceDir& current_dir,
166                                std::vector<SourceDir>* dest,
167                                Err* err) {
168   return ListValueExtractor(value, dest, err,
169                             RelativeDirConverter(build_settings, current_dir));
170 }
171
172 bool ExtractListOfLabels(const Value& value,
173                          const SourceDir& current_dir,
174                          const Label& current_toolchain,
175                          LabelTargetVector* dest,
176                          Err* err) {
177   return ListValueExtractor(value, dest, err,
178                             LabelPtrResolver<Target>(current_dir,
179                                                      current_toolchain));
180 }
181
182 bool ExtractListOfUniqueLabels(const Value& value,
183                                const SourceDir& current_dir,
184                                const Label& current_toolchain,
185                                UniqueVector<Label>* dest,
186                                Err* err) {
187   return ListValueUniqueExtractor(value, dest, err,
188                                   LabelResolver<Config>(current_dir,
189                                                         current_toolchain));
190 }
191
192 bool ExtractListOfUniqueLabels(const Value& value,
193                                const SourceDir& current_dir,
194                                const Label& current_toolchain,
195                                UniqueVector<LabelConfigPair>* dest,
196                                Err* err) {
197   return ListValueUniqueExtractor(value, dest, err,
198                                   LabelPtrResolver<Config>(current_dir,
199                                                            current_toolchain));
200 }
201
202 bool ExtractListOfUniqueLabels(const Value& value,
203                                const SourceDir& current_dir,
204                                const Label& current_toolchain,
205                                UniqueVector<LabelTargetPair>* dest,
206                                Err* err) {
207   return ListValueUniqueExtractor(value, dest, err,
208                                   LabelPtrResolver<Target>(current_dir,
209                                                            current_toolchain));
210 }
211
212 bool ExtractRelativeFile(const BuildSettings* build_settings,
213                          const Value& value,
214                          const SourceDir& current_dir,
215                          SourceFile* file,
216                          Err* err) {
217   RelativeFileConverter converter(build_settings, current_dir);
218   return converter(value, file, err);
219 }