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 24 namespace llvm { 25 namespace sys { 26 namespace 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 /// 49 class 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 58 public: 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 78 typedef 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. 83 const_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. 88 const_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. 93 inline 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. 100 inline 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. 115 void 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. 127 void 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. 137 void 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. 151 void 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. 164 void 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 "". 178 const 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 /// "". 189 const 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 "". 197 const 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 "". 207 const 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 "". 217 const 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. 229 const 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. 245 const 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. 259 const 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 265 bool 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. 276 void 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. 284 bool 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. 292 bool 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. 300 bool 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. 308 bool 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. 316 bool 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. 324 bool 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. 332 bool 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. 340 bool 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. 346 bool 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. 352 bool is_relative(const Twine &path); 353 354 } // end namespace path 355 } // end namespace sys 356 } // end namespace llvm 357 358 #endif 359