Path.h revision 360784
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 24namespace llvm { 25namespace sys { 26namespace path { 27 28enum 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 52class 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 64public: 65 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 78class 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 89public: 90 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. 101const_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. 106const_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. 111reverse_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. 116reverse_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. 134void 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. 148void 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, false => /old 157/// /old, /old/, /new, true => /new 158/// /old/foo, /old, /new => /new/foo 159/// /old/foo, /old/, /new => /new/foo 160/// /old/foo, /old/, /new/ => /new/foo 161/// /oldfoo, /old, /new => /oldfoo 162/// /foo, <empty>, /new => /new/foo 163/// /foo, <empty>, new => new/foo 164/// /old/foo, /old, <empty>, false => /foo 165/// /old/foo, /old, <empty>, true => foo 166/// @endcode 167/// 168/// @param Path If \a Path starts with \a OldPrefix modify to instead 169/// start with \a NewPrefix. 170/// @param OldPrefix The path prefix to strip from \a Path. Any trailing 171/// path separator is ignored if strict is true. 172/// @param NewPrefix The path prefix to replace \a NewPrefix with. 173/// @param style The path separator style 174/// @param strict If strict is true, a directory separator following 175/// \a OldPrefix will also be stripped. Otherwise, directory 176/// separators will only be matched and stripped when present 177/// in \a OldPrefix. 178/// @result true if \a Path begins with OldPrefix 179bool replace_path_prefix(SmallVectorImpl<char> &Path, 180 const StringRef &OldPrefix, const StringRef &NewPrefix, 181 Style style = Style::native, bool strict = false); 182 183/// Append to path. 184/// 185/// @code 186/// /foo + bar/f => /foo/bar/f 187/// /foo/ + bar/f => /foo/bar/f 188/// foo + bar/f => foo/bar/f 189/// @endcode 190/// 191/// @param path Set to \a path + \a component. 192/// @param a The component to be appended to \a path. 193void append(SmallVectorImpl<char> &path, const Twine &a, 194 const Twine &b = "", 195 const Twine &c = "", 196 const Twine &d = ""); 197 198void append(SmallVectorImpl<char> &path, Style style, const Twine &a, 199 const Twine &b = "", const Twine &c = "", const Twine &d = ""); 200 201/// Append to path. 202/// 203/// @code 204/// /foo + [bar,f] => /foo/bar/f 205/// /foo/ + [bar,f] => /foo/bar/f 206/// foo + [bar,f] => foo/bar/f 207/// @endcode 208/// 209/// @param path Set to \a path + [\a begin, \a end). 210/// @param begin Start of components to append. 211/// @param end One past the end of components to append. 212void append(SmallVectorImpl<char> &path, const_iterator begin, 213 const_iterator end, Style style = Style::native); 214 215/// @} 216/// @name Transforms (or some other better name) 217/// @{ 218 219/// Convert path to the native form. This is used to give paths to users and 220/// operating system calls in the platform's normal way. For example, on Windows 221/// all '/' are converted to '\'. 222/// 223/// @param path A path that is transformed to native format. 224/// @param result Holds the result of the transformation. 225void native(const Twine &path, SmallVectorImpl<char> &result, 226 Style style = Style::native); 227 228/// Convert path to the native form in place. This is used to give paths to 229/// users and operating system calls in the platform's normal way. For example, 230/// on Windows all '/' are converted to '\'. 231/// 232/// @param path A path that is transformed to native format. 233void native(SmallVectorImpl<char> &path, Style style = Style::native); 234 235/// Replaces backslashes with slashes if Windows. 236/// 237/// @param path processed path 238/// @result The result of replacing backslashes with forward slashes if Windows. 239/// On Unix, this function is a no-op because backslashes are valid path 240/// chracters. 241std::string convert_to_slash(StringRef path, Style style = Style::native); 242 243/// @} 244/// @name Lexical Observers 245/// @{ 246 247/// Get root name. 248/// 249/// @code 250/// //net/hello => //net 251/// c:/hello => c: (on Windows, on other platforms nothing) 252/// /hello => <empty> 253/// @endcode 254/// 255/// @param path Input path. 256/// @result The root name of \a path if it has one, otherwise "". 257StringRef root_name(StringRef path, Style style = Style::native); 258 259/// Get root directory. 260/// 261/// @code 262/// /goo/hello => / 263/// c:/hello => / 264/// d/file.txt => <empty> 265/// @endcode 266/// 267/// @param path Input path. 268/// @result The root directory of \a path if it has one, otherwise 269/// "". 270StringRef root_directory(StringRef path, Style style = Style::native); 271 272/// Get root path. 273/// 274/// Equivalent to root_name + root_directory. 275/// 276/// @param path Input path. 277/// @result The root path of \a path if it has one, otherwise "". 278StringRef root_path(StringRef path, Style style = Style::native); 279 280/// Get relative path. 281/// 282/// @code 283/// C:\hello\world => hello\world 284/// foo/bar => foo/bar 285/// /foo/bar => foo/bar 286/// @endcode 287/// 288/// @param path Input path. 289/// @result The path starting after root_path if one exists, otherwise "". 290StringRef relative_path(StringRef path, Style style = Style::native); 291 292/// Get parent path. 293/// 294/// @code 295/// / => <empty> 296/// /foo => / 297/// foo/../bar => foo/.. 298/// @endcode 299/// 300/// @param path Input path. 301/// @result The parent path of \a path if one exists, otherwise "". 302StringRef parent_path(StringRef path, Style style = Style::native); 303 304/// Get filename. 305/// 306/// @code 307/// /foo.txt => foo.txt 308/// . => . 309/// .. => .. 310/// / => / 311/// @endcode 312/// 313/// @param path Input path. 314/// @result The filename part of \a path. This is defined as the last component 315/// of \a path. Similar to the POSIX "basename" utility. 316StringRef filename(StringRef path, Style style = Style::native); 317 318/// Get stem. 319/// 320/// If filename contains a dot but not solely one or two dots, result is the 321/// substring of filename ending at (but not including) the last dot. Otherwise 322/// it is filename. 323/// 324/// @code 325/// /foo/bar.txt => bar 326/// /foo/bar => bar 327/// /foo/.txt => <empty> 328/// /foo/. => . 329/// /foo/.. => .. 330/// @endcode 331/// 332/// @param path Input path. 333/// @result The stem of \a path. 334StringRef stem(StringRef path, Style style = Style::native); 335 336/// Get extension. 337/// 338/// If filename contains a dot but not solely one or two dots, result is the 339/// substring of filename starting at (and including) the last dot, and ending 340/// at the end of \a path. Otherwise "". 341/// 342/// @code 343/// /foo/bar.txt => .txt 344/// /foo/bar => <empty> 345/// /foo/.txt => .txt 346/// @endcode 347/// 348/// @param path Input path. 349/// @result The extension of \a path. 350StringRef extension(StringRef path, Style style = Style::native); 351 352/// Check whether the given char is a path separator on the host OS. 353/// 354/// @param value a character 355/// @result true if \a value is a path separator character on the host OS 356bool is_separator(char value, Style style = Style::native); 357 358/// Return the preferred separator for this platform. 359/// 360/// @result StringRef of the preferred separator, null-terminated. 361StringRef get_separator(Style style = Style::native); 362 363/// Get the typical temporary directory for the system, e.g., 364/// "/var/tmp" or "C:/TEMP" 365/// 366/// @param erasedOnReboot Whether to favor a path that is erased on reboot 367/// rather than one that potentially persists longer. This parameter will be 368/// ignored if the user or system has set the typical environment variable 369/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. 370/// 371/// @param result Holds the resulting path name. 372void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); 373 374/// Get the user's home directory. 375/// 376/// @param result Holds the resulting path name. 377/// @result True if a home directory is set, false otherwise. 378bool home_directory(SmallVectorImpl<char> &result); 379 380/// Has root name? 381/// 382/// root_name != "" 383/// 384/// @param path Input path. 385/// @result True if the path has a root name, false otherwise. 386bool has_root_name(const Twine &path, Style style = Style::native); 387 388/// Has root directory? 389/// 390/// root_directory != "" 391/// 392/// @param path Input path. 393/// @result True if the path has a root directory, false otherwise. 394bool has_root_directory(const Twine &path, Style style = Style::native); 395 396/// Has root path? 397/// 398/// root_path != "" 399/// 400/// @param path Input path. 401/// @result True if the path has a root path, false otherwise. 402bool has_root_path(const Twine &path, Style style = Style::native); 403 404/// Has relative path? 405/// 406/// relative_path != "" 407/// 408/// @param path Input path. 409/// @result True if the path has a relative path, false otherwise. 410bool has_relative_path(const Twine &path, Style style = Style::native); 411 412/// Has parent path? 413/// 414/// parent_path != "" 415/// 416/// @param path Input path. 417/// @result True if the path has a parent path, false otherwise. 418bool has_parent_path(const Twine &path, Style style = Style::native); 419 420/// Has filename? 421/// 422/// filename != "" 423/// 424/// @param path Input path. 425/// @result True if the path has a filename, false otherwise. 426bool has_filename(const Twine &path, Style style = Style::native); 427 428/// Has stem? 429/// 430/// stem != "" 431/// 432/// @param path Input path. 433/// @result True if the path has a stem, false otherwise. 434bool has_stem(const Twine &path, Style style = Style::native); 435 436/// Has extension? 437/// 438/// extension != "" 439/// 440/// @param path Input path. 441/// @result True if the path has a extension, false otherwise. 442bool has_extension(const Twine &path, Style style = Style::native); 443 444/// Is path absolute? 445/// 446/// @param path Input path. 447/// @result True if the path is absolute, false if it is not. 448bool is_absolute(const Twine &path, Style style = Style::native); 449 450/// Is path relative? 451/// 452/// @param path Input path. 453/// @result True if the path is relative, false if it is not. 454bool is_relative(const Twine &path, Style style = Style::native); 455 456/// Remove redundant leading "./" pieces and consecutive separators. 457/// 458/// @param path Input path. 459/// @result The cleaned-up \a path. 460StringRef remove_leading_dotslash(StringRef path, Style style = Style::native); 461 462/// In-place remove any './' and optionally '../' components from a path. 463/// 464/// @param path processed path 465/// @param remove_dot_dot specify if '../' (except for leading "../") should be 466/// removed 467/// @result True if path was changed 468bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false, 469 Style style = Style::native); 470 471#if defined(_WIN32) 472std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16); 473#endif 474 475} // end namespace path 476} // end namespace sys 477} // end namespace llvm 478 479#endif 480