1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file.
4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value_extractors.h"
6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/build_settings.h"
8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h"
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/label.h"
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/source_dir.h"
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/source_file.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "tools/gn/target.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "tools/gn/value.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace {
16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Sets the error and returns false on failure.
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template<typename T, class Converter>
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ListValueExtractor(const Value& value,
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        std::vector<T>* dest,
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        Err* err,
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        const Converter& converter) {
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!value.VerifyTypeIs(Value::LIST, err))
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const std::vector<Value>& input_list = value.list_value();
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  dest->resize(input_list.size());
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < input_list.size(); i++) {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!converter(input_list[i], &(*dest)[i], err))
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Like the above version but extracts to a UniqueVector and sets the error if
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// there are duplicates.
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)template<typename T, class Converter>
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ListValueUniqueExtractor(const Value& value,
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              UniqueVector<T>* dest,
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              Err* err,
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              const Converter& converter) {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!value.VerifyTypeIs(Value::LIST, err))
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const std::vector<Value>& input_list = value.list_value();
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < input_list.size(); i++) {
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    T new_one;
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!converter(input_list[i], &new_one, err))
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!dest->push_back(new_one)) {
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Already in the list, throw error.
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *err = Err(input_list[i], "Duplicate item in list");
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      size_t previous_index = dest->IndexOf(new_one);
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      err->AppendSubErr(Err(input_list[previous_index],
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            "This was the previous definition."));
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// This extractor rejects files with system-absolute file paths. If we need
62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// that in the future, we'll have to add some flag to control this.
63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstruct RelativeFileConverter {
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RelativeFileConverter(const BuildSettings* build_settings_in,
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        const SourceDir& current_dir_in)
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : build_settings(build_settings_in),
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        current_dir(current_dir_in) {
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool operator()(const Value& v, SourceFile* out, Err* err) const {
70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (!v.VerifyTypeIs(Value::STRING, err))
71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return false;
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *out = current_dir.ResolveRelativeFile(v.string_value(),
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                           build_settings->root_path_utf8());
74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (out->is_system_absolute()) {
75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      *err = Err(v, "System-absolute file path.",
76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          "You can't list a system-absolute file path here. Please include "
77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          "only files in\nthe source tree. Maybe you meant to begin with two "
78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          "slashes to indicate an\nabsolute path in the source tree?");
79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return false;
80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    }
81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return true;
82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const BuildSettings* build_settings;
84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const SourceDir& current_dir;
85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch};
86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstruct RelativeDirConverter {
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RelativeDirConverter(const BuildSettings* build_settings_in,
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       const SourceDir& current_dir_in)
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : build_settings(build_settings_in),
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        current_dir(current_dir_in) {
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  bool operator()(const Value& v, SourceDir* out, Err* err) const {
94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (!v.VerifyTypeIs(Value::STRING, err))
95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return false;
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *out = current_dir.ResolveRelativeDir(v.string_value(),
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                          build_settings->root_path_utf8());
98d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return true;
99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const BuildSettings* build_settings;
101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const SourceDir& current_dir;
102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch};
103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Fills in a label.
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)template<typename T> struct LabelResolver {
106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  LabelResolver(const SourceDir& current_dir_in,
107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                const Label& current_toolchain_in)
108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      : current_dir(current_dir_in),
109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        current_toolchain(current_toolchain_in) {}
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool operator()(const Value& v, Label* out, Err* err) const {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!v.VerifyTypeIs(Value::STRING, err))
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    *out = Label::Resolve(current_dir, current_toolchain, v, err);
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return !err->has_error();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const SourceDir& current_dir;
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Label& current_toolchain;
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Fills the label part of a LabelPtrPair, leaving the pointer null.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate<typename T> struct LabelPtrResolver {
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LabelPtrResolver(const SourceDir& current_dir_in,
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   const Label& current_toolchain_in)
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : current_dir(current_dir_in),
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        current_toolchain(current_toolchain_in) {}
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool operator()(const Value& v, LabelPtrPair<T>* out, Err* err) const {
127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (!v.VerifyTypeIs(Value::STRING, err))
128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return false;
1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    out->label = Label::Resolve(current_dir, current_toolchain, v, err);
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    out->origin = v.origin();
131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return !err->has_error();
132d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
133d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const SourceDir& current_dir;
134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Label& current_toolchain;
135d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch};
136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}  // namespace
138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool ExtractListOfStringValues(const Value& value,
140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                               std::vector<std::string>* dest,
141d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                               Err* err) {
142d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value.VerifyTypeIs(Value::LIST, err))
143d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return false;
144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const std::vector<Value>& input_list = value.list_value();
145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  dest->reserve(input_list.size());
146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  for (size_t i = 0; i < input_list.size(); i++) {
147d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (!input_list[i].VerifyTypeIs(Value::STRING, err))
148d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return false;
149d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    dest->push_back(input_list[i].string_value());
150d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
151d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return true;
152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
153d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ExtractListOfRelativeFiles(const BuildSettings* build_settings,
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                const Value& value,
156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                const SourceDir& current_dir,
157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                std::vector<SourceFile>* files,
158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                Err* err) {
159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return ListValueExtractor(value, files, err,
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                            RelativeFileConverter(build_settings, current_dir));
161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ExtractListOfRelativeDirs(const BuildSettings* build_settings,
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const Value& value,
165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                               const SourceDir& current_dir,
166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                               std::vector<SourceDir>* dest,
167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                               Err* err) {
168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return ListValueExtractor(value, dest, err,
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                            RelativeDirConverter(build_settings, current_dir));
170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool ExtractListOfLabels(const Value& value,
173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                         const SourceDir& current_dir,
174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                         const Label& current_toolchain,
1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         LabelTargetVector* dest,
1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         Err* err) {
1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return ListValueExtractor(value, dest, err,
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            LabelPtrResolver<Target>(current_dir,
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                     current_toolchain));
180d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ExtractListOfUniqueLabels(const Value& value,
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const SourceDir& current_dir,
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const Label& current_toolchain,
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               UniqueVector<Label>* dest,
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               Err* err) {
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ListValueUniqueExtractor(value, dest, err,
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  LabelResolver<Config>(current_dir,
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                        current_toolchain));
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ExtractListOfUniqueLabels(const Value& value,
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const SourceDir& current_dir,
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const Label& current_toolchain,
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               UniqueVector<LabelConfigPair>* dest,
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               Err* err) {
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return ListValueUniqueExtractor(value, dest, err,
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  LabelPtrResolver<Config>(current_dir,
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                           current_toolchain));
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ExtractListOfUniqueLabels(const Value& value,
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               const SourceDir& current_dir,
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               const Label& current_toolchain,
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               UniqueVector<LabelTargetPair>* dest,
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               Err* err) {
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ListValueUniqueExtractor(value, dest, err,
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  LabelPtrResolver<Target>(current_dir,
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                           current_toolchain));
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ExtractRelativeFile(const BuildSettings* build_settings,
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const Value& value,
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const SourceDir& current_dir,
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         SourceFile* file,
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         Err* err) {
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RelativeFileConverter converter(build_settings, current_dir);
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return converter(value, file, err);
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
220