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/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 an input iterator that iterates over the individual components in 34 /// \a path. The 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 /// Traversing backwards is possible with \a reverse_iterator 40 /// 41 /// Iteration examples. Each component is separated by ',': 42 /// @code 43 /// / => / 44 /// /foo => /,foo 45 /// foo/ => foo,. 46 /// /foo/bar => /,foo,bar 47 /// ../ => ..,. 48 /// C:\foo\bar => C:,/,foo,bar 49 /// @endcode 50 class const_iterator 51 : public std::iterator<std::input_iterator_tag, const StringRef> { 52 StringRef Path; ///< The entire path. 53 StringRef Component; ///< The current component. Not necessarily in Path. 54 size_t Position; ///< The iterators current position within Path. 55 56 // An end iterator has Position = Path.size() + 1. 57 friend const_iterator begin(StringRef path); 58 friend const_iterator end(StringRef path); 59 60 public: 61 reference operator*() const { return Component; } 62 pointer operator->() const { return &Component; } 63 const_iterator &operator++(); // preincrement 64 const_iterator &operator++(int); // postincrement 65 bool operator==(const const_iterator &RHS) const; 66 bool operator!=(const const_iterator &RHS) const { return !(*this == RHS); } 67 68 /// @brief Difference in bytes between this and RHS. 69 ptrdiff_t operator-(const const_iterator &RHS) const; 70 }; 71 72 /// @brief Reverse path iterator. 73 /// 74 /// This is an input iterator that iterates over the individual components in 75 /// \a path in reverse order. The traversal order is exactly reversed from that 76 /// of \a const_iterator 77 class reverse_iterator 78 : public std::iterator<std::input_iterator_tag, const StringRef> { 79 StringRef Path; ///< The entire path. 80 StringRef Component; ///< The current component. Not necessarily in Path. 81 size_t Position; ///< The iterators current position within Path. 82 83 friend reverse_iterator rbegin(StringRef path); 84 friend reverse_iterator rend(StringRef path); 85 86 public: 87 reference operator*() const { return Component; } 88 pointer operator->() const { return &Component; } 89 reverse_iterator &operator++(); // preincrement 90 reverse_iterator &operator++(int); // postincrement 91 bool operator==(const reverse_iterator &RHS) const; 92 bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); } 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 Append to path. 146 /// 147 /// @code 148 /// /foo + bar/f => /foo/bar/f 149 /// /foo/ + bar/f => /foo/bar/f 150 /// foo + bar/f => foo/bar/f 151 /// @endcode 152 /// 153 /// @param path Set to \a path + \a component. 154 /// @param a The component to be appended to \a path. 155 void append(SmallVectorImpl<char> &path, const Twine &a, 156 const Twine &b = "", 157 const Twine &c = "", 158 const Twine &d = ""); 159 160 /// @brief Append to path. 161 /// 162 /// @code 163 /// /foo + [bar,f] => /foo/bar/f 164 /// /foo/ + [bar,f] => /foo/bar/f 165 /// foo + [bar,f] => foo/bar/f 166 /// @endcode 167 /// 168 /// @param path Set to \a path + [\a begin, \a end). 169 /// @param begin Start of components to append. 170 /// @param end One past the end of components to append. 171 void append(SmallVectorImpl<char> &path, 172 const_iterator begin, const_iterator end); 173 174 /// @} 175 /// @name Transforms (or some other better name) 176 /// @{ 177 178 /// Convert path to the native form. This is used to give paths to users and 179 /// operating system calls in the platform's normal way. For example, on Windows 180 /// all '/' are converted to '\'. 181 /// 182 /// @param path A path that is transformed to native format. 183 /// @param result Holds the result of the transformation. 184 void native(const Twine &path, SmallVectorImpl<char> &result); 185 186 /// Convert path to the native form in place. This is used to give paths to 187 /// users and operating system calls in the platform's normal way. For example, 188 /// on Windows all '/' are converted to '\'. 189 /// 190 /// @param path A path that is transformed to native format. 191 void native(SmallVectorImpl<char> &path); 192 193 /// @} 194 /// @name Lexical Observers 195 /// @{ 196 197 /// @brief Get root name. 198 /// 199 /// @code 200 /// //net/hello => //net 201 /// c:/hello => c: (on Windows, on other platforms nothing) 202 /// /hello => <empty> 203 /// @endcode 204 /// 205 /// @param path Input path. 206 /// @result The root name of \a path if it has one, otherwise "". 207 StringRef root_name(StringRef path); 208 209 /// @brief Get root directory. 210 /// 211 /// @code 212 /// /goo/hello => / 213 /// c:/hello => / 214 /// d/file.txt => <empty> 215 /// @endcode 216 /// 217 /// @param path Input path. 218 /// @result The root directory of \a path if it has one, otherwise 219 /// "". 220 StringRef root_directory(StringRef path); 221 222 /// @brief Get root path. 223 /// 224 /// Equivalent to root_name + root_directory. 225 /// 226 /// @param path Input path. 227 /// @result The root path of \a path if it has one, otherwise "". 228 StringRef root_path(StringRef path); 229 230 /// @brief Get relative path. 231 /// 232 /// @code 233 /// C:\hello\world => hello\world 234 /// foo/bar => foo/bar 235 /// /foo/bar => foo/bar 236 /// @endcode 237 /// 238 /// @param path Input path. 239 /// @result The path starting after root_path if one exists, otherwise "". 240 StringRef relative_path(StringRef path); 241 242 /// @brief Get parent path. 243 /// 244 /// @code 245 /// / => <empty> 246 /// /foo => / 247 /// foo/../bar => foo/.. 248 /// @endcode 249 /// 250 /// @param path Input path. 251 /// @result The parent path of \a path if one exists, otherwise "". 252 StringRef parent_path(StringRef path); 253 254 /// @brief Get filename. 255 /// 256 /// @code 257 /// /foo.txt => foo.txt 258 /// . => . 259 /// .. => .. 260 /// / => / 261 /// @endcode 262 /// 263 /// @param path Input path. 264 /// @result The filename part of \a path. This is defined as the last component 265 /// of \a path. 266 StringRef filename(StringRef path); 267 268 /// @brief Get stem. 269 /// 270 /// If filename contains a dot but not solely one or two dots, result is the 271 /// substring of filename ending at (but not including) the last dot. Otherwise 272 /// it is filename. 273 /// 274 /// @code 275 /// /foo/bar.txt => bar 276 /// /foo/bar => bar 277 /// /foo/.txt => <empty> 278 /// /foo/. => . 279 /// /foo/.. => .. 280 /// @endcode 281 /// 282 /// @param path Input path. 283 /// @result The stem of \a path. 284 StringRef stem(StringRef path); 285 286 /// @brief Get extension. 287 /// 288 /// If filename contains a dot but not solely one or two dots, result is the 289 /// substring of filename starting at (and including) the last dot, and ending 290 /// at the end of \a path. Otherwise "". 291 /// 292 /// @code 293 /// /foo/bar.txt => .txt 294 /// /foo/bar => <empty> 295 /// /foo/.txt => .txt 296 /// @endcode 297 /// 298 /// @param path Input path. 299 /// @result The extension of \a path. 300 StringRef extension(StringRef path); 301 302 /// @brief Check whether the given char is a path separator on the host OS. 303 /// 304 /// @param value a character 305 /// @result true if \a value is a path separator character on the host OS 306 bool is_separator(char value); 307 308 /// @brief Return the preferred separator for this platform. 309 /// 310 /// @result StringRef of the preferred separator, null-terminated. 311 StringRef get_separator(); 312 313 /// @brief Get the typical temporary directory for the system, e.g., 314 /// "/var/tmp" or "C:/TEMP" 315 /// 316 /// @param erasedOnReboot Whether to favor a path that is erased on reboot 317 /// rather than one that potentially persists longer. This parameter will be 318 /// ignored if the user or system has set the typical environment variable 319 /// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. 320 /// 321 /// @param result Holds the resulting path name. 322 void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); 323 324 /// @brief Get the user's home directory. 325 /// 326 /// @param result Holds the resulting path name. 327 /// @result True if a home directory is set, false otherwise. 328 bool home_directory(SmallVectorImpl<char> &result); 329 330 /// @brief Has root name? 331 /// 332 /// root_name != "" 333 /// 334 /// @param path Input path. 335 /// @result True if the path has a root name, false otherwise. 336 bool has_root_name(const Twine &path); 337 338 /// @brief Has root directory? 339 /// 340 /// root_directory != "" 341 /// 342 /// @param path Input path. 343 /// @result True if the path has a root directory, false otherwise. 344 bool has_root_directory(const Twine &path); 345 346 /// @brief Has root path? 347 /// 348 /// root_path != "" 349 /// 350 /// @param path Input path. 351 /// @result True if the path has a root path, false otherwise. 352 bool has_root_path(const Twine &path); 353 354 /// @brief Has relative path? 355 /// 356 /// relative_path != "" 357 /// 358 /// @param path Input path. 359 /// @result True if the path has a relative path, false otherwise. 360 bool has_relative_path(const Twine &path); 361 362 /// @brief Has parent path? 363 /// 364 /// parent_path != "" 365 /// 366 /// @param path Input path. 367 /// @result True if the path has a parent path, false otherwise. 368 bool has_parent_path(const Twine &path); 369 370 /// @brief Has filename? 371 /// 372 /// filename != "" 373 /// 374 /// @param path Input path. 375 /// @result True if the path has a filename, false otherwise. 376 bool has_filename(const Twine &path); 377 378 /// @brief Has stem? 379 /// 380 /// stem != "" 381 /// 382 /// @param path Input path. 383 /// @result True if the path has a stem, false otherwise. 384 bool has_stem(const Twine &path); 385 386 /// @brief Has extension? 387 /// 388 /// extension != "" 389 /// 390 /// @param path Input path. 391 /// @result True if the path has a extension, false otherwise. 392 bool has_extension(const Twine &path); 393 394 /// @brief Is path absolute? 395 /// 396 /// @param path Input path. 397 /// @result True if the path is absolute, false if it is not. 398 bool is_absolute(const Twine &path); 399 400 /// @brief Is path relative? 401 /// 402 /// @param path Input path. 403 /// @result True if the path is relative, false if it is not. 404 bool is_relative(const Twine &path); 405 406 } // end namespace path 407 } // end namespace sys 408 } // end namespace llvm 409 410 #endif 411