OR-Tools  9.6
path.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_BASE_PATH_H_
15 #define OR_TOOLS_BASE_PATH_H_
16 
17 #include <initializer_list>
18 #include <string>
19 #include <utility>
20 
21 #include "absl/strings/string_view.h"
22 
23 // A set of file pathname manipulation routines.
24 // Calls to each of the following functions assume their input is
25 // well-formed (for some currently nebulous definition of the word).
26 // You can get a well-formed path by using file::CleanPath(), and
27 // future versions of this API may require this.
28 //
29 // This collection is largely modelled on Python's os.path module.
30 
31 // Filenames are restricted to ASCII characters in most filesystems at
32 // Google. There are additional restrictions and quirks for some
33 // filesystems. For example, see file/colossus/base/cfs_path.h for
34 // filename character set restrictions for Colossus.
35 //
36 // One additional filename quirk: for legacy reasons, filenames of
37 // the forms:
38 // localhost:pathname
39 // hostname:pathname
40 // hostname.domainname:pathname
41 // will all route to //file/localfile and use only the pathname part, so
42 // long as hostname/hostname.domainname refer to the current host. The
43 // primary implication of this behavior is that filenames that do not
44 // begin with a leading '/' and that have a ':' before any '/' may be
45 // interpreted differently depending on the hostname where they are
46 // evaluated.
47 
48 namespace file {
49 
50 namespace internal {
51 // Not part of the public API.
52 std::string JoinPathImpl(bool honor_abs,
53  std::initializer_list<absl::string_view> paths);
54 } // namespace internal
55 
56 // Join multiple paths together.
57 // JoinPath and JoinPathRespectAbsolute have slightly different semantics.
58 // JoinPath unconditionally joins all paths together, whereas
59 // JoinPathRespectAbsolute ignores any segments prior to the last absolute
60 // path. For example:
61 //
62 // Arguments | JoinPath | JoinPathRespectAbsolute
63 // ---------------------------+---------------------+-----------------------
64 // 'foo', 'bar' | foo/bar | foo/bar
65 // '/foo', 'bar' | /foo/bar | /foo/bar
66 // '/foo/', 'bar' | /foo/bar | /foo/bar
67 // '/foo', '/bar' | /foo/bar | /bar
68 // '/foo/', '/bar' | /foo/bar | /bar
69 // '/foo', '/bar', '/baz' | /foo/bar/baz | /baz
70 //
71 // The first path may be relative or absolute. All subsequent paths will be
72 // treated as relative paths, regardless of whether or not they start with a
73 // leading '/'. That is, all paths will be concatenated together, with the
74 // appropriate path separator inserted in between.
75 // Arguments must be convertible to absl::string_view.
76 //
77 // Usage:
78 // string path = file::JoinPath("/cns", dirname, filename);
79 // string path = file::JoinPath(FLAGS_test_srcdir, filename);
80 //
81 // 0, 1, 2-path specializations exist to optimize common cases.
82 inline std::string JoinPath() { return std::string(); }
83 inline std::string JoinPath(absl::string_view path) {
84  return std::string(path.data(), path.size());
85 }
86 std::string JoinPath(absl::string_view path1, absl::string_view path2);
87 template <typename... T>
88 inline std::string JoinPath(absl::string_view path1, absl::string_view path2,
89  absl::string_view path3, const T&... args) {
90  return internal::JoinPathImpl(/*honor_abs=*/false,
91  {path1, path2, path3, args...});
92 }
93 
94 // Join multiple paths together, respecting intermediate absolute paths.
95 // All paths will be joined together, but if any of the paths is absolute
96 // (as defined by IsAbsolutePath()), all prior path segments will be ignored.
97 // This is the behavior of the old File::JoinPath().
98 // Arguments must be convertible to absl::string_view.
99 //
100 // Usage:
101 // string path = file::JoinPathRespectAbsolute("/cns", dirname, filename);
102 // string path = file::JoinPathRespectAbsolute(FLAGS_test_srcdir, filename);
103 template <typename... T>
104 inline std::string JoinPathRespectAbsolute(const T&... args) {
105  return internal::JoinPathImpl(/*honor_abs=*/true, {args...});
106 }
107 
108 // Return true if path is absolute.
109 bool IsAbsolutePath(absl::string_view path);
110 
111 // If path is non-empty and doesn't already end with a slash, append one
112 // to the end.
113 std::string AddSlash(absl::string_view path);
114 
115 // Returns the part of the path before the final "/", EXCEPT:
116 // * If there is a single leading "/" in the path, the result will be the
117 // leading "/".
118 // * If there is no "/" in the path, the result is the empty prefix of the
119 // input string.
120 absl::string_view Dirname(absl::string_view path);
121 
122 // Return the parts of the path, split on the final "/". If there is no
123 // "/" in the path, the first part of the output is empty and the second
124 // is the input. If the only "/" in the path is the first character, it is
125 // the first part of the output.
126 std::pair<absl::string_view, absl::string_view> SplitPath(
127  absl::string_view path);
128 
129 // Returns the part of the path after the final "/". If there is no
130 // "/" in the path, the result is the same as the input.
131 // Note that this function's behavior differs from the Unix basename
132 // command if path ends with "/". For such paths, this function returns the
133 // empty string.
134 absl::string_view Basename(absl::string_view path);
135 
136 // Returns the part of the basename of path prior to the final ".". If
137 // there is no "." in the basename, this is equivalent to file::Basename(path).
138 absl::string_view Stem(absl::string_view path);
139 
140 // Returns the part of the basename of path after the final ".". If
141 // there is no "." in the basename, the result is empty.
142 absl::string_view Extension(absl::string_view path);
143 
144 // ********************************************************
145 // Path cleaning utilities.
146 //
147 // NOTE: FileFactory implementations should probably clean paths they
148 // receive as needed. They should only clean the pieces of path they
149 // understand (in the case of wrapping-functionality like
150 // /readaheadfile or /encryptedfile). It cannot universally be done
151 // cleanly with common logic.
152 //
153 // Common sorts of surprises along those lines:
154 // * file/zipfile allows '/' and '.' in file *names* (and has no directory
155 // structure).
156 // * Colossus probably shouldn't collapse "ttl=8/../" into "/"
157 
158 // Collapse duplicate "/"s, resolve ".." and "." path elements, remove
159 // trailing "/".
160 //
161 // NOTE: This respects relative vs. absolute paths, but does not
162 // invoke any system calls (getcwd(2)) in order to resolve relative
163 // paths wrt actual working directory. That is, this is purely a
164 // string manipulation, completely independent of process state.
165 std::string CleanPath(absl::string_view path);
166 
167 // Similar to CleanPath, but only collapses duplicate "/"s. (Some
168 // filesystems allow "." and ".." in filenames.)
169 std::string CollapseSlashes(absl::string_view path);
170 
171 } // namespace file
172 
173 #endif // OR_TOOLS_BASE_PATH_H_
std::string JoinPathImpl(bool honor_abs, std::initializer_list< absl::string_view > paths)
Definition: path.cc:41
absl::string_view Dirname(absl::string_view path)
Definition: path.cc:105
absl::string_view Stem(absl::string_view path)
Definition: path.cc:129
std::string CleanPath(const absl::string_view unclean_path)
Definition: path.cc:137
std::string AddSlash(absl::string_view path)
Definition: path.cc:96
std::string CollapseSlashes(absl::string_view path)
Definition: path.cc:218
std::pair< absl::string_view, absl::string_view > SplitPath(absl::string_view path)
Definition: path.cc:113
std::string JoinPath(absl::string_view path1, absl::string_view path2)
Definition: path.cc:25
bool IsAbsolutePath(absl::string_view path)
Definition: path.cc:92
absl::string_view Basename(absl::string_view path)
Definition: path.cc:109
std::string JoinPathRespectAbsolute(const T &... args)
Definition: path.h:104
absl::string_view Extension(absl::string_view path)
Definition: path.cc:133