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/err.h" 8 #include "tools/gn/label.h" 9 #include "tools/gn/source_dir.h" 10 #include "tools/gn/source_file.h" 11 12 namespace { 13 14 // This extractor rejects files with system-absolute file paths. If we need 15 // that in the future, we'll have to add some flag to control this. 16 struct RelativeFileConverter { 17 RelativeFileConverter(const SourceDir& current_dir_in) 18 : current_dir(current_dir_in) {} 19 bool operator()(const Value& v, SourceFile* out, Err* err) const { 20 if (!v.VerifyTypeIs(Value::STRING, err)) 21 return false; 22 *out = current_dir.ResolveRelativeFile(v.string_value()); 23 if (out->is_system_absolute()) { 24 *err = Err(v, "System-absolute file path.", 25 "You can't list a system-absolute file path here. Please include " 26 "only files in\nthe source tree. Maybe you meant to begin with two " 27 "slashes to indicate an\nabsolute path in the source tree?"); 28 return false; 29 } 30 return true; 31 } 32 const SourceDir& current_dir; 33 }; 34 35 struct RelativeDirConverter { 36 RelativeDirConverter(const SourceDir& current_dir_in) 37 : current_dir(current_dir_in) {} 38 bool operator()(const Value& v, SourceDir* out, Err* err) const { 39 if (!v.VerifyTypeIs(Value::STRING, err)) 40 return false; 41 *out = current_dir.ResolveRelativeDir(v.string_value()); 42 return true; 43 } 44 const SourceDir& current_dir; 45 }; 46 47 struct LabelResolver { 48 LabelResolver(const SourceDir& current_dir_in, 49 const Label& current_toolchain_in) 50 : current_dir(current_dir_in), 51 current_toolchain(current_toolchain_in) {} 52 bool operator()(const Value& v, Label* out, Err* err) const { 53 if (!v.VerifyTypeIs(Value::STRING, err)) 54 return false; 55 *out = Label::Resolve(current_dir, current_toolchain, v, err); 56 return !err->has_error(); 57 } 58 const SourceDir& current_dir; 59 const Label& current_toolchain; 60 }; 61 62 } // namespace 63 64 bool ExtractListOfStringValues(const Value& value, 65 std::vector<std::string>* dest, 66 Err* err) { 67 if (!value.VerifyTypeIs(Value::LIST, err)) 68 return false; 69 const std::vector<Value>& input_list = value.list_value(); 70 dest->reserve(input_list.size()); 71 for (size_t i = 0; i < input_list.size(); i++) { 72 if (!input_list[i].VerifyTypeIs(Value::STRING, err)) 73 return false; 74 dest->push_back(input_list[i].string_value()); 75 } 76 return true; 77 } 78 79 bool ExtractListOfRelativeFiles(const Value& value, 80 const SourceDir& current_dir, 81 std::vector<SourceFile>* files, 82 Err* err) { 83 return ListValueExtractor(value, files, err, 84 RelativeFileConverter(current_dir)); 85 } 86 87 bool ExtractListOfRelativeDirs(const Value& value, 88 const SourceDir& current_dir, 89 std::vector<SourceDir>* dest, 90 Err* err) { 91 return ListValueExtractor(value, dest, err, 92 RelativeDirConverter(current_dir)); 93 } 94 95 bool ExtractListOfLabels(const Value& value, 96 const SourceDir& current_dir, 97 const Label& current_toolchain, 98 std::vector<Label>* dest, 99 Err* err) { 100 return ListValueExtractor(value, dest, err, 101 LabelResolver(current_dir, current_toolchain)); 102 } 103