From 9dfb1ee2fc1b6e312105ad2062ec963d28b916e6 Mon Sep 17 00:00:00 2001 From: Laszlo Csomor Date: Mon, 26 Feb 2018 09:17:02 -0800 Subject: 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 --- src/tools/runfiles/runfiles.cc | 101 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/tools/runfiles/runfiles.cc (limited to 'src/tools/runfiles/runfiles.cc') 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 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 -- cgit v1.2.3