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.
5 #include "tools/gn/value_extractors.h"
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"
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
) {
23 bool operator()(const Value
& v
, SourceFile
* out
, Err
* err
) const {
24 if (!v
.VerifyTypeIs(Value::STRING
, err
))
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?");
37 const BuildSettings
* build_settings
;
38 const SourceDir
& current_dir
;
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
) {
47 bool operator()(const Value
& v
, SourceDir
* out
, Err
* err
) const {
48 if (!v
.VerifyTypeIs(Value::STRING
, err
))
50 *out
= current_dir
.ResolveRelativeDir(v
.string_value(),
51 build_settings
->root_path_utf8());
54 const BuildSettings
* build_settings
;
55 const SourceDir
& current_dir
;
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
))
67 out
->label
= Label::Resolve(current_dir
, current_toolchain
, v
, err
);
68 out
->origin
= v
.origin();
69 return !err
->has_error();
71 const SourceDir
& current_dir
;
72 const Label
& current_toolchain
;
77 bool ExtractListOfStringValues(const Value
& value
,
78 std::vector
<std::string
>* dest
,
80 if (!value
.VerifyTypeIs(Value::LIST
, err
))
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
))
87 dest
->push_back(input_list
[i
].string_value());
92 bool ExtractListOfRelativeFiles(const BuildSettings
* build_settings
,
94 const SourceDir
& current_dir
,
95 std::vector
<SourceFile
>* files
,
97 return ListValueExtractor(value
, files
, err
,
98 RelativeFileConverter(build_settings
, current_dir
));
101 bool ExtractListOfRelativeDirs(const BuildSettings
* build_settings
,
103 const SourceDir
& current_dir
,
104 std::vector
<SourceDir
>* dest
,
106 return ListValueExtractor(value
, dest
, err
,
107 RelativeDirConverter(build_settings
, current_dir
));
110 bool ExtractListOfLabels(const Value
& value
,
111 const SourceDir
& current_dir
,
112 const Label
& current_toolchain
,
113 LabelConfigVector
* dest
,
115 return ListValueExtractor(value
, dest
, err
,
116 LabelResolver
<Config
>(current_dir
,
120 bool ExtractListOfLabels(const Value
& value
,
121 const SourceDir
& current_dir
,
122 const Label
& current_toolchain
,
123 LabelTargetVector
* dest
,
125 return ListValueExtractor(value
, dest
, err
,
126 LabelResolver
<Target
>(current_dir
,
130 bool ExtractRelativeFile(const BuildSettings
* build_settings
,
132 const SourceDir
& current_dir
,
135 RelativeFileConverter
converter(build_settings
, current_dir
);
136 return converter(value
, file
, err
);