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 "base/files/file_util.h"
6 #include "gn/err.h"
7 #include "gn/filesystem_utils.h"
8 #include "gn/functions.h"
9 #include "gn/input_conversion.h"
10 #include "gn/input_file.h"
11 #include "gn/scheduler.h"
12
13 // TODO(brettw) consider removing this. I originally wrote it for making the
14 // WebKit bindings but misundersood what was required, and didn't need to
15 // use this. This seems to have a high potential for misuse.
16
17 namespace functions {
18
19 const char kReadFile[] = "read_file";
20 const char kReadFile_HelpShort[] = "read_file: Read a file into a variable.";
21 const char kReadFile_Help[] =
22 R"(read_file: Read a file into a variable.
23
24 read_file(filename, input_conversion)
25
26 Whitespace will be trimmed from the end of the file. Throws an error if the
27 file can not be opened.
28
29 Arguments
30
31 filename
32 Filename to read, relative to the build file.
33
34 input_conversion
35 Controls how the file is read and parsed. See `gn help io_conversion`.
36
37 Example
38
39 lines = read_file("foo.txt", "list lines")
40 )";
41
RunReadFile(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)42 Value RunReadFile(Scope* scope,
43 const FunctionCallNode* function,
44 const std::vector<Value>& args,
45 Err* err) {
46 if (args.size() != 2) {
47 *err = Err(function->function(), "Wrong number of arguments to read_file",
48 "I expected two arguments.");
49 return Value();
50 }
51 if (!args[0].VerifyTypeIs(Value::STRING, err))
52 return Value();
53
54 // Compute the file name.
55 const SourceDir& cur_dir = scope->GetSourceDir();
56 SourceFile source_file = cur_dir.ResolveRelativeFile(
57 args[0], err, scope->settings()->build_settings()->root_path_utf8());
58 if (err->has_error())
59 return Value();
60 base::FilePath file_path =
61 scope->settings()->build_settings()->GetFullPath(source_file);
62
63 // Ensure that everything is recomputed if the read file changes.
64 g_scheduler->AddGenDependency(file_path);
65
66 // Read contents.
67 std::string file_contents;
68 if (!base::ReadFileToString(file_path, &file_contents)) {
69 *err = Err(args[0], "Could not read file.",
70 "I resolved this to \"" + FilePathToUTF8(file_path) + "\".");
71 return Value();
72 }
73
74 return ConvertInputToValue(scope->settings(), file_contents, function,
75 args[1], err);
76 }
77
78 } // namespace functions
79