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