/home/arjun/llvm-project/llvm/include/llvm/Support/Path.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file declares the llvm::sys::path namespace. It is designed after |
10 | | // TR2/boost filesystem (v3), but modified to remove exception handling and the |
11 | | // path class. |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #ifndef LLVM_SUPPORT_PATH_H |
16 | | #define LLVM_SUPPORT_PATH_H |
17 | | |
18 | | #include "llvm/ADT/Twine.h" |
19 | | #include "llvm/ADT/iterator.h" |
20 | | #include "llvm/Support/DataTypes.h" |
21 | | #include <iterator> |
22 | | #include <system_error> |
23 | | |
24 | | namespace llvm { |
25 | | namespace sys { |
26 | | namespace path { |
27 | | |
28 | | enum class Style { windows, posix, native }; |
29 | | |
30 | | /// @name Lexical Component Iterator |
31 | | /// @{ |
32 | | |
33 | | /// Path iterator. |
34 | | /// |
35 | | /// This is an input iterator that iterates over the individual components in |
36 | | /// \a path. The traversal order is as follows: |
37 | | /// * The root-name element, if present. |
38 | | /// * The root-directory element, if present. |
39 | | /// * Each successive filename element, if present. |
40 | | /// * Dot, if one or more trailing non-root slash characters are present. |
41 | | /// Traversing backwards is possible with \a reverse_iterator |
42 | | /// |
43 | | /// Iteration examples. Each component is separated by ',': |
44 | | /// @code |
45 | | /// / => / |
46 | | /// /foo => /,foo |
47 | | /// foo/ => foo,. |
48 | | /// /foo/bar => /,foo,bar |
49 | | /// ../ => ..,. |
50 | | /// C:\foo\bar => C:,\,foo,bar |
51 | | /// @endcode |
52 | | class const_iterator |
53 | | : public iterator_facade_base<const_iterator, std::input_iterator_tag, |
54 | | const StringRef> { |
55 | | StringRef Path; ///< The entire path. |
56 | | StringRef Component; ///< The current component. Not necessarily in Path. |
57 | | size_t Position = 0; ///< The iterators current position within Path. |
58 | | Style S = Style::native; ///< The path style to use. |
59 | | |
60 | | // An end iterator has Position = Path.size() + 1. |
61 | | friend const_iterator begin(StringRef path, Style style); |
62 | | friend const_iterator end(StringRef path); |
63 | | |
64 | | public: |
65 | 0 | reference operator*() const { return Component; } |
66 | | const_iterator &operator++(); // preincrement |
67 | | bool operator==(const const_iterator &RHS) const; |
68 | | |
69 | | /// Difference in bytes between this and RHS. |
70 | | ptrdiff_t operator-(const const_iterator &RHS) const; |
71 | | }; |
72 | | |
73 | | /// Reverse path iterator. |
74 | | /// |
75 | | /// This is an input iterator that iterates over the individual components in |
76 | | /// \a path in reverse order. The traversal order is exactly reversed from that |
77 | | /// of \a const_iterator |
78 | | class reverse_iterator |
79 | | : public iterator_facade_base<reverse_iterator, std::input_iterator_tag, |
80 | | const StringRef> { |
81 | | StringRef Path; ///< The entire path. |
82 | | StringRef Component; ///< The current component. Not necessarily in Path. |
83 | | size_t Position = 0; ///< The iterators current position within Path. |
84 | | Style S = Style::native; ///< The path style to use. |
85 | | |
86 | | friend reverse_iterator rbegin(StringRef path, Style style); |
87 | | friend reverse_iterator rend(StringRef path); |
88 | | |
89 | | public: |
90 | 2 | reference operator*() const { return Component; } |
91 | | reverse_iterator &operator++(); // preincrement |
92 | | bool operator==(const reverse_iterator &RHS) const; |
93 | | |
94 | | /// Difference in bytes between this and RHS. |
95 | | ptrdiff_t operator-(const reverse_iterator &RHS) const; |
96 | | }; |
97 | | |
98 | | /// Get begin iterator over \a path. |
99 | | /// @param path Input path. |
100 | | /// @returns Iterator initialized with the first component of \a path. |
101 | | const_iterator begin(StringRef path, Style style = Style::native); |
102 | | |
103 | | /// Get end iterator over \a path. |
104 | | /// @param path Input path. |
105 | | /// @returns Iterator initialized to the end of \a path. |
106 | | const_iterator end(StringRef path); |
107 | | |
108 | | /// Get reverse begin iterator over \a path. |
109 | | /// @param path Input path. |
110 | | /// @returns Iterator initialized with the first reverse component of \a path. |
111 | | reverse_iterator rbegin(StringRef path, Style style = Style::native); |
112 | | |
113 | | /// Get reverse end iterator over \a path. |
114 | | /// @param path Input path. |
115 | | /// @returns Iterator initialized to the reverse end of \a path. |
116 | | reverse_iterator rend(StringRef path); |
117 | | |
118 | | /// @} |
119 | | /// @name Lexical Modifiers |
120 | | /// @{ |
121 | | |
122 | | /// Remove the last component from \a path unless it is the root dir. |
123 | | /// |
124 | | /// Similar to the POSIX "dirname" utility. |
125 | | /// |
126 | | /// @code |
127 | | /// directory/filename.cpp => directory/ |
128 | | /// directory/ => directory |
129 | | /// filename.cpp => <empty> |
130 | | /// / => / |
131 | | /// @endcode |
132 | | /// |
133 | | /// @param path A path that is modified to not have a file component. |
134 | | void remove_filename(SmallVectorImpl<char> &path, Style style = Style::native); |
135 | | |
136 | | /// Replace the file extension of \a path with \a extension. |
137 | | /// |
138 | | /// @code |
139 | | /// ./filename.cpp => ./filename.extension |
140 | | /// ./filename => ./filename.extension |
141 | | /// ./ => ./.extension |
142 | | /// @endcode |
143 | | /// |
144 | | /// @param path A path that has its extension replaced with \a extension. |
145 | | /// @param extension The extension to be added. It may be empty. It may also |
146 | | /// optionally start with a '.', if it does not, one will be |
147 | | /// prepended. |
148 | | void replace_extension(SmallVectorImpl<char> &path, const Twine &extension, |
149 | | Style style = Style::native); |
150 | | |
151 | | /// Replace matching path prefix with another path. |
152 | | /// |
153 | | /// @code |
154 | | /// /foo, /old, /new => /foo |
155 | | /// /old, /old, /new => /new |
156 | | /// /old, /old/, /new => /old |
157 | | /// /old/foo, /old, /new => /new/foo |
158 | | /// /old/foo, /old/, /new => /new/foo |
159 | | /// /old/foo, /old/, /new/ => /new/foo |
160 | | /// /oldfoo, /old, /new => /oldfoo |
161 | | /// /foo, <empty>, /new => /new/foo |
162 | | /// /foo, <empty>, new => new/foo |
163 | | /// /old/foo, /old, <empty> => /foo |
164 | | /// @endcode |
165 | | /// |
166 | | /// @param Path If \a Path starts with \a OldPrefix modify to instead |
167 | | /// start with \a NewPrefix. |
168 | | /// @param OldPrefix The path prefix to strip from \a Path. |
169 | | /// @param NewPrefix The path prefix to replace \a NewPrefix with. |
170 | | /// @param style The style used to match the prefix. Exact match using |
171 | | /// Posix style, case/separator insensitive match for Windows style. |
172 | | /// @result true if \a Path begins with OldPrefix |
173 | | bool replace_path_prefix(SmallVectorImpl<char> &Path, StringRef OldPrefix, |
174 | | StringRef NewPrefix, |
175 | | Style style = Style::native); |
176 | | |
177 | | /// Append to path. |
178 | | /// |
179 | | /// @code |
180 | | /// /foo + bar/f => /foo/bar/f |
181 | | /// /foo/ + bar/f => /foo/bar/f |
182 | | /// foo + bar/f => foo/bar/f |
183 | | /// @endcode |
184 | | /// |
185 | | /// @param path Set to \a path + \a component. |
186 | | /// @param a The component to be appended to \a path. |
187 | | void append(SmallVectorImpl<char> &path, const Twine &a, |
188 | | const Twine &b = "", |
189 | | const Twine &c = "", |
190 | | const Twine &d = ""); |
191 | | |
192 | | void append(SmallVectorImpl<char> &path, Style style, const Twine &a, |
193 | | const Twine &b = "", const Twine &c = "", const Twine &d = ""); |
194 | | |
195 | | /// Append to path. |
196 | | /// |
197 | | /// @code |
198 | | /// /foo + [bar,f] => /foo/bar/f |
199 | | /// /foo/ + [bar,f] => /foo/bar/f |
200 | | /// foo + [bar,f] => foo/bar/f |
201 | | /// @endcode |
202 | | /// |
203 | | /// @param path Set to \a path + [\a begin, \a end). |
204 | | /// @param begin Start of components to append. |
205 | | /// @param end One past the end of components to append. |
206 | | void append(SmallVectorImpl<char> &path, const_iterator begin, |
207 | | const_iterator end, Style style = Style::native); |
208 | | |
209 | | /// @} |
210 | | /// @name Transforms (or some other better name) |
211 | | /// @{ |
212 | | |
213 | | /// Convert path to the native form. This is used to give paths to users and |
214 | | /// operating system calls in the platform's normal way. For example, on Windows |
215 | | /// all '/' are converted to '\'. |
216 | | /// |
217 | | /// @param path A path that is transformed to native format. |
218 | | /// @param result Holds the result of the transformation. |
219 | | void native(const Twine &path, SmallVectorImpl<char> &result, |
220 | | Style style = Style::native); |
221 | | |
222 | | /// Convert path to the native form in place. This is used to give paths to |
223 | | /// users and operating system calls in the platform's normal way. For example, |
224 | | /// on Windows all '/' are converted to '\'. |
225 | | /// |
226 | | /// @param path A path that is transformed to native format. |
227 | | void native(SmallVectorImpl<char> &path, Style style = Style::native); |
228 | | |
229 | | /// Replaces backslashes with slashes if Windows. |
230 | | /// |
231 | | /// @param path processed path |
232 | | /// @result The result of replacing backslashes with forward slashes if Windows. |
233 | | /// On Unix, this function is a no-op because backslashes are valid path |
234 | | /// chracters. |
235 | | std::string convert_to_slash(StringRef path, Style style = Style::native); |
236 | | |
237 | | /// @} |
238 | | /// @name Lexical Observers |
239 | | /// @{ |
240 | | |
241 | | /// Get root name. |
242 | | /// |
243 | | /// @code |
244 | | /// //net/hello => //net |
245 | | /// c:/hello => c: (on Windows, on other platforms nothing) |
246 | | /// /hello => <empty> |
247 | | /// @endcode |
248 | | /// |
249 | | /// @param path Input path. |
250 | | /// @result The root name of \a path if it has one, otherwise "". |
251 | | StringRef root_name(StringRef path, Style style = Style::native); |
252 | | |
253 | | /// Get root directory. |
254 | | /// |
255 | | /// @code |
256 | | /// /goo/hello => / |
257 | | /// c:/hello => / |
258 | | /// d/file.txt => <empty> |
259 | | /// @endcode |
260 | | /// |
261 | | /// @param path Input path. |
262 | | /// @result The root directory of \a path if it has one, otherwise |
263 | | /// "". |
264 | | StringRef root_directory(StringRef path, Style style = Style::native); |
265 | | |
266 | | /// Get root path. |
267 | | /// |
268 | | /// Equivalent to root_name + root_directory. |
269 | | /// |
270 | | /// @param path Input path. |
271 | | /// @result The root path of \a path if it has one, otherwise "". |
272 | | StringRef root_path(StringRef path, Style style = Style::native); |
273 | | |
274 | | /// Get relative path. |
275 | | /// |
276 | | /// @code |
277 | | /// C:\hello\world => hello\world |
278 | | /// foo/bar => foo/bar |
279 | | /// /foo/bar => foo/bar |
280 | | /// @endcode |
281 | | /// |
282 | | /// @param path Input path. |
283 | | /// @result The path starting after root_path if one exists, otherwise "". |
284 | | StringRef relative_path(StringRef path, Style style = Style::native); |
285 | | |
286 | | /// Get parent path. |
287 | | /// |
288 | | /// @code |
289 | | /// / => <empty> |
290 | | /// /foo => / |
291 | | /// foo/../bar => foo/.. |
292 | | /// @endcode |
293 | | /// |
294 | | /// @param path Input path. |
295 | | /// @result The parent path of \a path if one exists, otherwise "". |
296 | | StringRef parent_path(StringRef path, Style style = Style::native); |
297 | | |
298 | | /// Get filename. |
299 | | /// |
300 | | /// @code |
301 | | /// /foo.txt => foo.txt |
302 | | /// . => . |
303 | | /// .. => .. |
304 | | /// / => / |
305 | | /// @endcode |
306 | | /// |
307 | | /// @param path Input path. |
308 | | /// @result The filename part of \a path. This is defined as the last component |
309 | | /// of \a path. Similar to the POSIX "basename" utility. |
310 | | StringRef filename(StringRef path, Style style = Style::native); |
311 | | |
312 | | /// Get stem. |
313 | | /// |
314 | | /// If filename contains a dot but not solely one or two dots, result is the |
315 | | /// substring of filename ending at (but not including) the last dot. Otherwise |
316 | | /// it is filename. |
317 | | /// |
318 | | /// @code |
319 | | /// /foo/bar.txt => bar |
320 | | /// /foo/bar => bar |
321 | | /// /foo/.txt => <empty> |
322 | | /// /foo/. => . |
323 | | /// /foo/.. => .. |
324 | | /// @endcode |
325 | | /// |
326 | | /// @param path Input path. |
327 | | /// @result The stem of \a path. |
328 | | StringRef stem(StringRef path, Style style = Style::native); |
329 | | |
330 | | /// Get extension. |
331 | | /// |
332 | | /// If filename contains a dot but not solely one or two dots, result is the |
333 | | /// substring of filename starting at (and including) the last dot, and ending |
334 | | /// at the end of \a path. Otherwise "". |
335 | | /// |
336 | | /// @code |
337 | | /// /foo/bar.txt => .txt |
338 | | /// /foo/bar => <empty> |
339 | | /// /foo/.txt => .txt |
340 | | /// @endcode |
341 | | /// |
342 | | /// @param path Input path. |
343 | | /// @result The extension of \a path. |
344 | | StringRef extension(StringRef path, Style style = Style::native); |
345 | | |
346 | | /// Check whether the given char is a path separator on the host OS. |
347 | | /// |
348 | | /// @param value a character |
349 | | /// @result true if \a value is a path separator character on the host OS |
350 | | bool is_separator(char value, Style style = Style::native); |
351 | | |
352 | | /// Return the preferred separator for this platform. |
353 | | /// |
354 | | /// @result StringRef of the preferred separator, null-terminated. |
355 | | StringRef get_separator(Style style = Style::native); |
356 | | |
357 | | /// Get the typical temporary directory for the system, e.g., |
358 | | /// "/var/tmp" or "C:/TEMP" |
359 | | /// |
360 | | /// @param erasedOnReboot Whether to favor a path that is erased on reboot |
361 | | /// rather than one that potentially persists longer. This parameter will be |
362 | | /// ignored if the user or system has set the typical environment variable |
363 | | /// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. |
364 | | /// |
365 | | /// @param result Holds the resulting path name. |
366 | | void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); |
367 | | |
368 | | /// Get the user's home directory. |
369 | | /// |
370 | | /// @param result Holds the resulting path name. |
371 | | /// @result True if a home directory is set, false otherwise. |
372 | | bool home_directory(SmallVectorImpl<char> &result); |
373 | | |
374 | | /// Get the directory where installed packages should put their |
375 | | /// machine-local cache, e.g. $XDG_CACHE_HOME. |
376 | | /// |
377 | | /// @param result Holds the resulting path name. |
378 | | /// @result True if the appropriate path was determined, it need not exist. |
379 | | bool cache_directory(SmallVectorImpl<char> &result); |
380 | | |
381 | | /// Has root name? |
382 | | /// |
383 | | /// root_name != "" |
384 | | /// |
385 | | /// @param path Input path. |
386 | | /// @result True if the path has a root name, false otherwise. |
387 | | bool has_root_name(const Twine &path, Style style = Style::native); |
388 | | |
389 | | /// Has root directory? |
390 | | /// |
391 | | /// root_directory != "" |
392 | | /// |
393 | | /// @param path Input path. |
394 | | /// @result True if the path has a root directory, false otherwise. |
395 | | bool has_root_directory(const Twine &path, Style style = Style::native); |
396 | | |
397 | | /// Has root path? |
398 | | /// |
399 | | /// root_path != "" |
400 | | /// |
401 | | /// @param path Input path. |
402 | | /// @result True if the path has a root path, false otherwise. |
403 | | bool has_root_path(const Twine &path, Style style = Style::native); |
404 | | |
405 | | /// Has relative path? |
406 | | /// |
407 | | /// relative_path != "" |
408 | | /// |
409 | | /// @param path Input path. |
410 | | /// @result True if the path has a relative path, false otherwise. |
411 | | bool has_relative_path(const Twine &path, Style style = Style::native); |
412 | | |
413 | | /// Has parent path? |
414 | | /// |
415 | | /// parent_path != "" |
416 | | /// |
417 | | /// @param path Input path. |
418 | | /// @result True if the path has a parent path, false otherwise. |
419 | | bool has_parent_path(const Twine &path, Style style = Style::native); |
420 | | |
421 | | /// Has filename? |
422 | | /// |
423 | | /// filename != "" |
424 | | /// |
425 | | /// @param path Input path. |
426 | | /// @result True if the path has a filename, false otherwise. |
427 | | bool has_filename(const Twine &path, Style style = Style::native); |
428 | | |
429 | | /// Has stem? |
430 | | /// |
431 | | /// stem != "" |
432 | | /// |
433 | | /// @param path Input path. |
434 | | /// @result True if the path has a stem, false otherwise. |
435 | | bool has_stem(const Twine &path, Style style = Style::native); |
436 | | |
437 | | /// Has extension? |
438 | | /// |
439 | | /// extension != "" |
440 | | /// |
441 | | /// @param path Input path. |
442 | | /// @result True if the path has a extension, false otherwise. |
443 | | bool has_extension(const Twine &path, Style style = Style::native); |
444 | | |
445 | | /// Is path absolute? |
446 | | /// |
447 | | /// @param path Input path. |
448 | | /// @result True if the path is absolute, false if it is not. |
449 | | bool is_absolute(const Twine &path, Style style = Style::native); |
450 | | |
451 | | /// Is path relative? |
452 | | /// |
453 | | /// @param path Input path. |
454 | | /// @result True if the path is relative, false if it is not. |
455 | | bool is_relative(const Twine &path, Style style = Style::native); |
456 | | |
457 | | /// Remove redundant leading "./" pieces and consecutive separators. |
458 | | /// |
459 | | /// @param path Input path. |
460 | | /// @result The cleaned-up \a path. |
461 | | StringRef remove_leading_dotslash(StringRef path, Style style = Style::native); |
462 | | |
463 | | /// In-place remove any './' and optionally '../' components from a path. |
464 | | /// |
465 | | /// @param path processed path |
466 | | /// @param remove_dot_dot specify if '../' (except for leading "../") should be |
467 | | /// removed |
468 | | /// @result True if path was changed |
469 | | bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false, |
470 | | Style style = Style::native); |
471 | | |
472 | | } // end namespace path |
473 | | } // end namespace sys |
474 | | } // end namespace llvm |
475 | | |
476 | | #endif |