value_extractors.cc revision f2477e01787aa58f445919b809d89e252beef54f
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 13namespace { 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. 17struct 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 41struct 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. 59template<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 77bool 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 92bool 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 101bool 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 110bool 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 120bool 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 130bool 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