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 13 namespace { 14 15 // This extractor rejects files with system-absolute file paths. If we need 16 // that in the future, we'll have to add some flag to control this. 17 struct RelativeFileConverter { 18 RelativeFileConverter(const BuildSettings* build_settings_in, 19 const SourceDir& current_dir_in) 20 : build_settings(build_settings_in), 21 current_dir(current_dir_in) { 22 } 23 bool operator()(const Value& v, SourceFile* out, Err* err) const { 24 if (!v.VerifyTypeIs(Value::STRING, err)) 25 return false; 26 *out = current_dir.ResolveRelativeFile(v.string_value(), 27 build_settings->root_path_utf8()); 28 if (out->is_system_absolute()) { 29 *err = Err(v, "System-absolute file path.", 30 "You can't list a system-absolute file path here. Please include " 31 "only files in\nthe source tree. Maybe you meant to begin with two " 32 "slashes to indicate an\nabsolute path in the source tree?"); 33 return false; 34 } 35 return true; 36 } 37 const BuildSettings* build_settings; 38 const SourceDir& current_dir; 39 }; 40 41 struct RelativeDirConverter { 42 RelativeDirConverter(const BuildSettings* build_settings_in, 43 const SourceDir& current_dir_in) 44 : build_settings(build_settings_in), 45 current_dir(current_dir_in) { 46 } 47 bool operator()(const Value& v, SourceDir* out, Err* err) const { 48 if (!v.VerifyTypeIs(Value::STRING, err)) 49 return false; 50 *out = current_dir.ResolveRelativeDir(v.string_value(), 51 build_settings->root_path_utf8()); 52 return true; 53 } 54 const BuildSettings* build_settings; 55 const SourceDir& current_dir; 56 }; 57 58 // Fills the label part of a LabelPtrPair, leaving the pointer null. 59 template<typename T> struct LabelResolver { 60 LabelResolver(const SourceDir& current_dir_in, 61 const Label& current_toolchain_in) 62 : current_dir(current_dir_in), 63 current_toolchain(current_toolchain_in) {} 64 bool operator()(const Value& v, LabelPtrPair<T>* out, Err* err) const { 65 if (!v.VerifyTypeIs(Value::STRING, err)) 66 return false; 67 out->label = Label::Resolve(current_dir, current_toolchain, v, err); 68 out->origin = v.origin(); 69 return !err->has_error(); 70 } 71 const SourceDir& current_dir; 72 const Label& current_toolchain; 73 }; 74 75 } // namespace 76 77 bool ExtractListOfStringValues(const Value& value, 78 std::vector<std::string>* dest, 79 Err* err) { 80 if (!value.VerifyTypeIs(Value::LIST, err)) 81 return false; 82 const std::vector<Value>& input_list = value.list_value(); 83 dest->reserve(input_list.size()); 84 for (size_t i = 0; i < input_list.size(); i++) { 85 if (!input_list[i].VerifyTypeIs(Value::STRING, err)) 86 return false; 87 dest->push_back(input_list[i].string_value()); 88 } 89 return true; 90 } 91 92 bool ExtractListOfRelativeFiles(const BuildSettings* build_settings, 93 const Value& value, 94 const SourceDir& current_dir, 95 std::vector<SourceFile>* files, 96 Err* err) { 97 return ListValueExtractor(value, files, err, 98 RelativeFileConverter(build_settings, current_dir)); 99 } 100 101 bool ExtractListOfRelativeDirs(const BuildSettings* build_settings, 102 const Value& value, 103 const SourceDir& current_dir, 104 std::vector<SourceDir>* dest, 105 Err* err) { 106 return ListValueExtractor(value, dest, err, 107 RelativeDirConverter(build_settings, current_dir)); 108 } 109 110 bool ExtractListOfLabels(const Value& value, 111 const SourceDir& current_dir, 112 const Label& current_toolchain, 113 LabelConfigVector* dest, 114 Err* err) { 115 return ListValueExtractor(value, dest, err, 116 LabelResolver<Config>(current_dir, 117 current_toolchain)); 118 } 119 120 bool ExtractListOfLabels(const Value& value, 121 const SourceDir& current_dir, 122 const Label& current_toolchain, 123 LabelTargetVector* dest, 124 Err* err) { 125 return ListValueExtractor(value, dest, err, 126 LabelResolver<Target>(current_dir, 127 current_toolchain)); 128 } 129 130 bool ExtractRelativeFile(const BuildSettings* build_settings, 131 const Value& value, 132 const SourceDir& current_dir, 133 SourceFile* file, 134 Err* err) { 135 RelativeFileConverter converter(build_settings, current_dir); 136 return converter(value, file, err); 137 } 138