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