blob: 22cecbb69a2a504b9b602033641992fa04d1b475 [file] [log] [blame]
Googlerebd28a92018-02-07 08:46:31 -08001// Copyright 2018 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#ifndef BAZEL_SRC_MAIN_CPP_RC_FILE_H_
15#define BAZEL_SRC_MAIN_CPP_RC_FILE_H_
16
Googlerebd28a92018-02-07 08:46:31 -080017#include <memory>
Googlerebd28a92018-02-07 08:46:31 -080018#include <string>
19#include <vector>
20
21#include "src/main/cpp/workspace_layout.h"
Googlerd7feff52024-08-09 00:07:35 -070022#include "absl/container/flat_hash_map.h"
Googlerb74b7cf2024-09-11 23:30:14 -070023#include "absl/functional/function_ref.h"
Googlerebd28a92018-02-07 08:46:31 -080024
25namespace blaze {
26
27// Single option in an rc file.
28struct RcOption {
Googlerebd28a92018-02-07 08:46:31 -080029 std::string option;
Googler1980fdb2020-09-01 13:49:34 -070030 // Only keep the index of the source file to avoid copying the paths all over.
31 // This index points into the RcFile's canonical_source_paths() vector.
32 int source_index;
Googlerebd28a92018-02-07 08:46:31 -080033};
34
35// Reads and parses a single rc file with all its imports.
36class RcFile {
37 public:
38 // Constructs a parsed rc file object, or returns a nullptr and sets the
39 // error and error text on failure.
Googlerb74b7cf2024-09-11 23:30:14 -070040 using ReadFileFn =
41 absl::FunctionRef<bool(const std::string&, std::string*, std::string*)>;
42 using CanonicalizePathFn = absl::FunctionRef<std::string(const std::string&)>;
Googlerebd28a92018-02-07 08:46:31 -080043 enum class ParseError { NONE, UNREADABLE_FILE, INVALID_FORMAT, IMPORT_LOOP };
44 static std::unique_ptr<RcFile> Parse(
Googlerd7feff52024-08-09 00:07:35 -070045 const std::string& filename, const WorkspaceLayout* workspace_layout,
Googlerb74b7cf2024-09-11 23:30:14 -070046 const std::string& workspace, ParseError* error, std::string* error_text,
47 ReadFileFn read_file = &ReadFileDefault,
48 CanonicalizePathFn canonicalize_path = &CanonicalizePathDefault);
Googlerebd28a92018-02-07 08:46:31 -080049
Googler1980fdb2020-09-01 13:49:34 -070050 // Movable and copyable.
51 RcFile(const RcFile&) = default;
52 RcFile(RcFile&&) = default;
53 RcFile& operator=(const RcFile&) = default;
54 RcFile& operator=(RcFile&&) = default;
55
Googlerebd28a92018-02-07 08:46:31 -080056 // Returns all relevant rc sources for this file (including itself).
Googler1980fdb2020-09-01 13:49:34 -070057 const std::vector<std::string>& canonical_source_paths() const {
Laszlo Csomor9b83bd72018-12-17 08:42:44 -080058 return canonical_rcfile_paths_;
59 }
Googlerebd28a92018-02-07 08:46:31 -080060
61 // Command -> all options for that command (in order of appearance).
Googlerd7feff52024-08-09 00:07:35 -070062 using OptionMap = absl::flat_hash_map<std::string, std::vector<RcOption>>;
Googlerebd28a92018-02-07 08:46:31 -080063 const OptionMap& options() const { return options_; }
64
65 private:
Googlerd7feff52024-08-09 00:07:35 -070066 RcFile() = default;
Googlerebd28a92018-02-07 08:46:31 -080067
68 // Recursive call to parse a file and its imports.
69 ParseError ParseFile(const std::string& filename,
Googlerd7feff52024-08-09 00:07:35 -070070 const std::string& workspace,
71 const WorkspaceLayout& workspace_layout,
Googlerb74b7cf2024-09-11 23:30:14 -070072 ReadFileFn read_file,
73 CanonicalizePathFn canonicalize_path,
Googlerd7feff52024-08-09 00:07:35 -070074 std::vector<std::string>& import_stack,
Googlerebd28a92018-02-07 08:46:31 -080075 std::string* error_text);
76
Googlerb74b7cf2024-09-11 23:30:14 -070077 static bool ReadFileDefault(const std::string& filename,
78 std::string* contents, std::string* error_msg);
79 static std::string CanonicalizePathDefault(const std::string& filename);
80
Googlerebd28a92018-02-07 08:46:31 -080081 // Full closure of rcfile paths imported from this file (including itself).
Laszlo Csomor9b83bd72018-12-17 08:42:44 -080082 // These are all canonical paths, created with blaze_util::MakeCanonical.
83 // This also means all of these paths should exist.
Googler1980fdb2020-09-01 13:49:34 -070084 std::vector<std::string> canonical_rcfile_paths_;
Googlerebd28a92018-02-07 08:46:31 -080085 // All options parsed from the file.
86 OptionMap options_;
87};
88
89} // namespace blaze
90
91#endif // BAZEL_SRC_MAIN_CPP_RC_FILE_H_