1//===- llvm/Support/PathV2.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_PATHV2_H 17#define LLVM_SUPPORT_PATHV2_H 18 19#include "llvm/ADT/SmallString.h" 20#include "llvm/ADT/Twine.h" 21#include "llvm/Support/DataTypes.h" 22#include <iterator> 23 24namespace llvm { 25namespace sys { 26namespace path { 27 28/// @name Lexical Component Iterator 29/// @{ 30 31/// @brief Path iterator. 32/// 33/// This is a bidirectional iterator that iterates over the individual 34/// components in \a path. The forward traversal order is as follows: 35/// * The root-name element, if present. 36/// * The root-directory element, if present. 37/// * Each successive filename element, if present. 38/// * Dot, if one or more trailing non-root slash characters are present. 39/// The backwards traversal order is the reverse of forward traversal. 40/// 41/// Iteration examples. Each component is separated by ',': 42/// / => / 43/// /foo => /,foo 44/// foo/ => foo,. 45/// /foo/bar => /,foo,bar 46/// ../ => ..,. 47/// C:\foo\bar => C:,/,foo,bar 48/// 49class const_iterator { 50 StringRef Path; //< The entire path. 51 StringRef Component; //< The current component. Not necessarily in Path. 52 size_t Position; //< The iterators current position within Path. 53 54 // An end iterator has Position = Path.size() + 1. 55 friend const_iterator begin(StringRef path); 56 friend const_iterator end(StringRef path); 57 58public: 59 typedef const StringRef value_type; 60 typedef ptrdiff_t difference_type; 61 typedef value_type &reference; 62 typedef value_type *pointer; 63 typedef std::bidirectional_iterator_tag iterator_category; 64 65 reference operator*() const { return Component; } 66 pointer operator->() const { return &Component; } 67 const_iterator &operator++(); // preincrement 68 const_iterator &operator++(int); // postincrement 69 const_iterator &operator--(); // predecrement 70 const_iterator &operator--(int); // postdecrement 71 bool operator==(const const_iterator &RHS) const; 72 bool operator!=(const const_iterator &RHS) const; 73 74 /// @brief Difference in bytes between this and RHS. 75 ptrdiff_t operator-(const const_iterator &RHS) const; 76}; 77 78typedef std::reverse_iterator<const_iterator> reverse_iterator; 79 80/// @brief Get begin iterator over \a path. 81/// @param path Input path. 82/// @returns Iterator initialized with the first component of \a path. 83const_iterator begin(StringRef path); 84 85/// @brief Get end iterator over \a path. 86/// @param path Input path. 87/// @returns Iterator initialized to the end of \a path. 88const_iterator end(StringRef path); 89 90/// @brief Get reverse begin iterator over \a path. 91/// @param path Input path. 92/// @returns Iterator initialized with the first reverse component of \a path. 93inline reverse_iterator rbegin(StringRef path) { 94 return reverse_iterator(end(path)); 95} 96 97/// @brief Get reverse end iterator over \a path. 98/// @param path Input path. 99/// @returns Iterator initialized to the reverse end of \a path. 100inline reverse_iterator rend(StringRef path) { 101 return reverse_iterator(begin(path)); 102} 103 104/// @} 105/// @name Lexical Modifiers 106/// @{ 107 108/// @brief Remove the last component from \a path unless it is the root dir. 109/// 110/// directory/filename.cpp => directory/ 111/// directory/ => directory 112/// / => / 113/// 114/// @param path A path that is modified to not have a file component. 115void remove_filename(SmallVectorImpl<char> &path); 116 117/// @brief Replace the file extension of \a path with \a extension. 118/// 119/// ./filename.cpp => ./filename.extension 120/// ./filename => ./filename.extension 121/// ./ => ./.extension 122/// 123/// @param path A path that has its extension replaced with \a extension. 124/// @param extension The extension to be added. It may be empty. It may also 125/// optionally start with a '.', if it does not, one will be 126/// prepended. 127void replace_extension(SmallVectorImpl<char> &path, const Twine &extension); 128 129/// @brief Append to path. 130/// 131/// /foo + bar/f => /foo/bar/f 132/// /foo/ + bar/f => /foo/bar/f 133/// foo + bar/f => foo/bar/f 134/// 135/// @param path Set to \a path + \a component. 136/// @param component The component to be appended to \a path. 137void append(SmallVectorImpl<char> &path, const Twine &a, 138 const Twine &b = "", 139 const Twine &c = "", 140 const Twine &d = ""); 141 142/// @brief Append to path. 143/// 144/// /foo + [bar,f] => /foo/bar/f 145/// /foo/ + [bar,f] => /foo/bar/f 146/// foo + [bar,f] => foo/bar/f 147/// 148/// @param path Set to \a path + [\a begin, \a end). 149/// @param begin Start of components to append. 150/// @param end One past the end of components to append. 151void append(SmallVectorImpl<char> &path, 152 const_iterator begin, const_iterator end); 153 154/// @} 155/// @name Transforms (or some other better name) 156/// @{ 157 158/// Convert path to the native form. This is used to give paths to users and 159/// operating system calls in the platform's normal way. For example, on Windows 160/// all '/' are converted to '\'. 161/// 162/// @param path A path that is transformed to native format. 163/// @param result Holds the result of the transformation. 164void native(const Twine &path, SmallVectorImpl<char> &result); 165 166/// @} 167/// @name Lexical Observers 168/// @{ 169 170/// @brief Get root name. 171/// 172/// //net/hello => //net 173/// c:/hello => c: (on Windows, on other platforms nothing) 174/// /hello => <empty> 175/// 176/// @param path Input path. 177/// @result The root name of \a path if it has one, otherwise "". 178const StringRef root_name(StringRef path); 179 180/// @brief Get root directory. 181/// 182/// /goo/hello => / 183/// c:/hello => / 184/// d/file.txt => <empty> 185/// 186/// @param path Input path. 187/// @result The root directory of \a path if it has one, otherwise 188/// "". 189const StringRef root_directory(StringRef path); 190 191/// @brief Get root path. 192/// 193/// Equivalent to root_name + root_directory. 194/// 195/// @param path Input path. 196/// @result The root path of \a path if it has one, otherwise "". 197const StringRef root_path(StringRef path); 198 199/// @brief Get relative path. 200/// 201/// C:\hello\world => hello\world 202/// foo/bar => foo/bar 203/// /foo/bar => foo/bar 204/// 205/// @param path Input path. 206/// @result The path starting after root_path if one exists, otherwise "". 207const StringRef relative_path(StringRef path); 208 209/// @brief Get parent path. 210/// 211/// / => <empty> 212/// /foo => / 213/// foo/../bar => foo/.. 214/// 215/// @param path Input path. 216/// @result The parent path of \a path if one exists, otherwise "". 217const StringRef parent_path(StringRef path); 218 219/// @brief Get filename. 220/// 221/// /foo.txt => foo.txt 222/// . => . 223/// .. => .. 224/// / => / 225/// 226/// @param path Input path. 227/// @result The filename part of \a path. This is defined as the last component 228/// of \a path. 229const StringRef filename(StringRef path); 230 231/// @brief Get stem. 232/// 233/// If filename contains a dot but not solely one or two dots, result is the 234/// substring of filename ending at (but not including) the last dot. Otherwise 235/// it is filename. 236/// 237/// /foo/bar.txt => bar 238/// /foo/bar => bar 239/// /foo/.txt => <empty> 240/// /foo/. => . 241/// /foo/.. => .. 242/// 243/// @param path Input path. 244/// @result The stem of \a path. 245const StringRef stem(StringRef path); 246 247/// @brief Get extension. 248/// 249/// If filename contains a dot but not solely one or two dots, result is the 250/// substring of filename starting at (and including) the last dot, and ending 251/// at the end of \a path. Otherwise "". 252/// 253/// /foo/bar.txt => .txt 254/// /foo/bar => <empty> 255/// /foo/.txt => .txt 256/// 257/// @param path Input path. 258/// @result The extension of \a path. 259const StringRef extension(StringRef path); 260 261/// @brief Check whether the given char is a path separator on the host OS. 262/// 263/// @param value a character 264/// @result true if \a value is a path separator character on the host OS 265bool is_separator(char value); 266 267/// @brief Get the typical temporary directory for the system, e.g., 268/// "/var/tmp" or "C:/TEMP" 269/// 270/// @param erasedOnReboot Whether to favor a path that is erased on reboot 271/// rather than one that potentially persists longer. This parameter will be 272/// ignored if the user or system has set the typical environment variable 273/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. 274/// 275/// @param Result Holds the resulting path name. 276void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); 277 278/// @brief Has root name? 279/// 280/// root_name != "" 281/// 282/// @param path Input path. 283/// @result True if the path has a root name, false otherwise. 284bool has_root_name(const Twine &path); 285 286/// @brief Has root directory? 287/// 288/// root_directory != "" 289/// 290/// @param path Input path. 291/// @result True if the path has a root directory, false otherwise. 292bool has_root_directory(const Twine &path); 293 294/// @brief Has root path? 295/// 296/// root_path != "" 297/// 298/// @param path Input path. 299/// @result True if the path has a root path, false otherwise. 300bool has_root_path(const Twine &path); 301 302/// @brief Has relative path? 303/// 304/// relative_path != "" 305/// 306/// @param path Input path. 307/// @result True if the path has a relative path, false otherwise. 308bool has_relative_path(const Twine &path); 309 310/// @brief Has parent path? 311/// 312/// parent_path != "" 313/// 314/// @param path Input path. 315/// @result True if the path has a parent path, false otherwise. 316bool has_parent_path(const Twine &path); 317 318/// @brief Has filename? 319/// 320/// filename != "" 321/// 322/// @param path Input path. 323/// @result True if the path has a filename, false otherwise. 324bool has_filename(const Twine &path); 325 326/// @brief Has stem? 327/// 328/// stem != "" 329/// 330/// @param path Input path. 331/// @result True if the path has a stem, false otherwise. 332bool has_stem(const Twine &path); 333 334/// @brief Has extension? 335/// 336/// extension != "" 337/// 338/// @param path Input path. 339/// @result True if the path has a extension, false otherwise. 340bool has_extension(const Twine &path); 341 342/// @brief Is path absolute? 343/// 344/// @param path Input path. 345/// @result True if the path is absolute, false if it is not. 346bool is_absolute(const Twine &path); 347 348/// @brief Is path relative? 349/// 350/// @param path Input path. 351/// @result True if the path is relative, false if it is not. 352bool is_relative(const Twine &path); 353 354} // end namespace path 355} // end namespace sys 356} // end namespace llvm 357 358#endif 359