diff options
author | Laszlo Csomor <laszlocsomor@google.com> | 2018-02-26 09:17:02 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-02-26 09:19:02 -0800 |
commit | 9dfb1ee2fc1b6e312105ad2062ec963d28b916e6 (patch) | |
tree | 23253b4f732d460512003242d663a07452661f88 /src/tools/runfiles/runfiles.cc | |
parent | 726df7e1cbf29422964e826d90019846a5c092fb (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.cc | 101 |
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 |