aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/runfiles/runfiles.cc
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2018-02-26 09:17:02 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-26 09:19:02 -0800
commit9dfb1ee2fc1b6e312105ad2062ec963d28b916e6 (patch)
tree23253b4f732d460512003242d663a07452661f88 /src/tools/runfiles/runfiles.cc
parent726df7e1cbf29422964e826d90019846a5c092fb (diff)
runfiles,C++: implement runfiles lib foundations
Implement the foundation of the C++ runfiles library, along with a directory-based Runfiles implementation. Subsequent commits will add more feataures: - manifest-based runfiles handling - creating list of envvars to pass to child processes - automatic Runfiles creation based on argv[0] and the envvars of this process See https://github.com/bazelbuild/bazel/issues/4460 Change-Id: Id5a38619a1ae874499f04523863081559360410c PiperOrigin-RevId: 187031518
Diffstat (limited to 'src/tools/runfiles/runfiles.cc')
-rw-r--r--src/tools/runfiles/runfiles.cc101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/tools/runfiles/runfiles.cc b/src/tools/runfiles/runfiles.cc
new file mode 100644
index 0000000000..9ff1f3f4c5
--- /dev/null
+++ b/src/tools/runfiles/runfiles.cc
@@ -0,0 +1,101 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "tools/runfiles/runfiles.h"
+
+namespace bazel {
+namespace runfiles {
+
+using std::string;
+
+namespace {
+
+class RunfilesImpl : public Runfiles {
+ public:
+ // TODO(laszlocsomor): implement Create(
+ // const string& argv0, function<string(const string&)> env_lookup, string*
+ // error);
+
+ string Rlocation(const string& path) const override;
+
+ // Returns the runtime-location of a given runfile.
+ //
+ // This method assumes that the caller already validated the `path`. See
+ // Runfiles::Rlocation for requirements.
+ virtual string RlocationChecked(const string& path) const = 0;
+
+ protected:
+ RunfilesImpl() {}
+ virtual ~RunfilesImpl() {}
+};
+
+// TODO(laszlocsomor): derive a ManifestBased class from RunfilesImpl.
+
+// Runfiles implementation that appends runfiles paths to the runfiles root.
+class DirectoryBased : public RunfilesImpl {
+ public:
+ DirectoryBased(string runfiles_path)
+ : runfiles_path_(std::move(runfiles_path)) {}
+ string RlocationChecked(const string& path) const override;
+
+ private:
+ DirectoryBased(const DirectoryBased&) = delete;
+ DirectoryBased(DirectoryBased&&) = delete;
+ DirectoryBased& operator=(const DirectoryBased&) = delete;
+ DirectoryBased& operator=(DirectoryBased&&) = delete;
+
+ const string runfiles_path_;
+};
+
+bool IsAbsolute(const string& path) {
+ if (path.empty()) {
+ return false;
+ }
+ char c = path.front();
+ return (c == '/') || (path.size() >= 3 &&
+ ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) &&
+ path[1] == ':' && (path[2] == '\\' || path[2] == '/'));
+}
+
+string RunfilesImpl::Rlocation(const string& path) const {
+ if (path.empty() || path.find("..") != string::npos) {
+ return std::move(string());
+ }
+ if (IsAbsolute(path)) {
+ return path;
+ }
+ return RlocationChecked(path);
+}
+
+string DirectoryBased::RlocationChecked(const string& path) const {
+ return std::move(runfiles_path_ + "/" + path);
+}
+
+} // namespace
+
+namespace testing {
+
+bool TestOnly_IsAbsolute(const string& path) { return IsAbsolute(path); }
+
+} // namespace testing
+
+Runfiles* Runfiles::CreateDirectoryBased(const string& directory_path,
+ string* error) {
+ // Note: `error` is intentionally unused because we don't expect any errors
+ // here. We expect an `error` pointer so that we may use it in the future if
+ // need be, without having to change the API.
+ return new DirectoryBased(directory_path);
+}
+
+} // namespace runfiles
+} // namespace bazel