Home | History | Annotate | Download | only in gn
      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 "tools/gn/err.h"
      7 #include "tools/gn/filesystem_utils.h"
      8 #include "tools/gn/functions.h"
      9 #include "tools/gn/input_conversion.h"
     10 #include "tools/gn/input_file.h"
     11 #include "tools/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[] =
     21     "read_file: Read a file into a variable.";
     22 const char kReadFile_Help[] =
     23     "read_file: Read a file into a variable.\n"
     24     "\n"
     25     "  read_file(filename, input_conversion)\n"
     26     "\n"
     27     "  Whitespace will be trimmed from the end of the file. Throws an error\n"
     28     "  if the file can not be opened.\n"
     29     "\n"
     30     "Arguments:\n"
     31     "\n"
     32     "  filename\n"
     33     "      Filename to read, relative to the build file.\n"
     34     "\n"
     35     "  input_conversion\n"
     36     "      Controls how the file is read and parsed.\n"
     37     "      See \"gn help input_conversion\".\n"
     38     "\n"
     39     "Example\n"
     40     "  lines = read_file(\"foo.txt\", \"list lines\")\n";
     41 
     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(args[0].string_value());
     57   base::FilePath file_path =
     58       scope->settings()->build_settings()->GetFullPath(source_file);
     59 
     60   // Ensure that everything is recomputed if the read file changes.
     61   g_scheduler->AddGenDependency(file_path);
     62 
     63   // Read contents.
     64   std::string file_contents;
     65   if (!base::ReadFileToString(file_path, &file_contents)) {
     66     *err = Err(args[0], "Could not read file.",
     67                "I resolved this to \"" + FilePathToUTF8(file_path) + "\".");
     68     return Value();
     69   }
     70 
     71   return ConvertInputToValue(scope->settings(), file_contents, function,
     72                              args[1], err);
     73 }
     74 
     75 }  // namespace functions
     76