1218885Sdim//===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10263508Sdim// This file declares the llvm::sys::path namespace. It is designed after 11263508Sdim// TR2/boost filesystem (v3), but modified to remove exception handling and the 12263508Sdim// path class. 13218885Sdim// 14218885Sdim//===----------------------------------------------------------------------===// 15218885Sdim 16263508Sdim#ifndef LLVM_SUPPORT_PATH_H 17263508Sdim#define LLVM_SUPPORT_PATH_H 18263508Sdim 19263508Sdim#include "llvm/ADT/SmallString.h" 20263508Sdim#include "llvm/ADT/Twine.h" 21263508Sdim#include "llvm/Support/DataTypes.h" 22263508Sdim#include <iterator> 23263508Sdim 24263508Sdimnamespace llvm { 25263508Sdimnamespace sys { 26263508Sdimnamespace path { 27263508Sdim 28263508Sdim/// @name Lexical Component Iterator 29263508Sdim/// @{ 30263508Sdim 31263508Sdim/// @brief Path iterator. 32263508Sdim/// 33263508Sdim/// This is a bidirectional iterator that iterates over the individual 34263508Sdim/// components in \a path. The forward traversal order is as follows: 35263508Sdim/// * The root-name element, if present. 36263508Sdim/// * The root-directory element, if present. 37263508Sdim/// * Each successive filename element, if present. 38263508Sdim/// * Dot, if one or more trailing non-root slash characters are present. 39263508Sdim/// The backwards traversal order is the reverse of forward traversal. 40263508Sdim/// 41263508Sdim/// Iteration examples. Each component is separated by ',': 42263508Sdim/// @code 43263508Sdim/// / => / 44263508Sdim/// /foo => /,foo 45263508Sdim/// foo/ => foo,. 46263508Sdim/// /foo/bar => /,foo,bar 47263508Sdim/// ../ => ..,. 48263508Sdim/// C:\foo\bar => C:,/,foo,bar 49263508Sdim/// @endcode 50263508Sdimclass const_iterator { 51263508Sdim StringRef Path; ///< The entire path. 52263508Sdim StringRef Component; ///< The current component. Not necessarily in Path. 53263508Sdim size_t Position; ///< The iterators current position within Path. 54263508Sdim 55263508Sdim // An end iterator has Position = Path.size() + 1. 56263508Sdim friend const_iterator begin(StringRef path); 57263508Sdim friend const_iterator end(StringRef path); 58263508Sdim 59263508Sdimpublic: 60263508Sdim typedef const StringRef value_type; 61263508Sdim typedef ptrdiff_t difference_type; 62263508Sdim typedef value_type &reference; 63263508Sdim typedef value_type *pointer; 64263508Sdim typedef std::bidirectional_iterator_tag iterator_category; 65263508Sdim 66263508Sdim reference operator*() const { return Component; } 67263508Sdim pointer operator->() const { return &Component; } 68263508Sdim const_iterator &operator++(); // preincrement 69263508Sdim const_iterator &operator++(int); // postincrement 70263508Sdim const_iterator &operator--(); // predecrement 71263508Sdim const_iterator &operator--(int); // postdecrement 72263508Sdim bool operator==(const const_iterator &RHS) const; 73263508Sdim bool operator!=(const const_iterator &RHS) const; 74263508Sdim 75263508Sdim /// @brief Difference in bytes between this and RHS. 76263508Sdim ptrdiff_t operator-(const const_iterator &RHS) const; 77263508Sdim}; 78263508Sdim 79263508Sdimtypedef std::reverse_iterator<const_iterator> reverse_iterator; 80263508Sdim 81263508Sdim/// @brief Get begin iterator over \a path. 82263508Sdim/// @param path Input path. 83263508Sdim/// @returns Iterator initialized with the first component of \a path. 84263508Sdimconst_iterator begin(StringRef path); 85263508Sdim 86263508Sdim/// @brief Get end iterator over \a path. 87263508Sdim/// @param path Input path. 88263508Sdim/// @returns Iterator initialized to the end of \a path. 89263508Sdimconst_iterator end(StringRef path); 90263508Sdim 91263508Sdim/// @brief Get reverse begin iterator over \a path. 92263508Sdim/// @param path Input path. 93263508Sdim/// @returns Iterator initialized with the first reverse component of \a path. 94263508Sdiminline reverse_iterator rbegin(StringRef path) { 95263508Sdim return reverse_iterator(end(path)); 96263508Sdim} 97263508Sdim 98263508Sdim/// @brief Get reverse end iterator over \a path. 99263508Sdim/// @param path Input path. 100263508Sdim/// @returns Iterator initialized to the reverse end of \a path. 101263508Sdiminline reverse_iterator rend(StringRef path) { 102263508Sdim return reverse_iterator(begin(path)); 103263508Sdim} 104263508Sdim 105263508Sdim/// @} 106263508Sdim/// @name Lexical Modifiers 107263508Sdim/// @{ 108263508Sdim 109263508Sdim/// @brief Remove the last component from \a path unless it is the root dir. 110263508Sdim/// 111263508Sdim/// @code 112263508Sdim/// directory/filename.cpp => directory/ 113263508Sdim/// directory/ => directory 114263508Sdim/// filename.cpp => <empty> 115263508Sdim/// / => / 116263508Sdim/// @endcode 117263508Sdim/// 118263508Sdim/// @param path A path that is modified to not have a file component. 119263508Sdimvoid remove_filename(SmallVectorImpl<char> &path); 120263508Sdim 121263508Sdim/// @brief Replace the file extension of \a path with \a extension. 122263508Sdim/// 123263508Sdim/// @code 124263508Sdim/// ./filename.cpp => ./filename.extension 125263508Sdim/// ./filename => ./filename.extension 126263508Sdim/// ./ => ./.extension 127263508Sdim/// @endcode 128263508Sdim/// 129263508Sdim/// @param path A path that has its extension replaced with \a extension. 130263508Sdim/// @param extension The extension to be added. It may be empty. It may also 131263508Sdim/// optionally start with a '.', if it does not, one will be 132263508Sdim/// prepended. 133263508Sdimvoid replace_extension(SmallVectorImpl<char> &path, const Twine &extension); 134263508Sdim 135263508Sdim/// @brief Append to path. 136263508Sdim/// 137263508Sdim/// @code 138263508Sdim/// /foo + bar/f => /foo/bar/f 139263508Sdim/// /foo/ + bar/f => /foo/bar/f 140263508Sdim/// foo + bar/f => foo/bar/f 141263508Sdim/// @endcode 142263508Sdim/// 143263508Sdim/// @param path Set to \a path + \a component. 144263508Sdim/// @param a The component to be appended to \a path. 145263508Sdimvoid append(SmallVectorImpl<char> &path, const Twine &a, 146263508Sdim const Twine &b = "", 147263508Sdim const Twine &c = "", 148263508Sdim const Twine &d = ""); 149263508Sdim 150263508Sdim/// @brief Append to path. 151263508Sdim/// 152263508Sdim/// @code 153263508Sdim/// /foo + [bar,f] => /foo/bar/f 154263508Sdim/// /foo/ + [bar,f] => /foo/bar/f 155263508Sdim/// foo + [bar,f] => foo/bar/f 156263508Sdim/// @endcode 157263508Sdim/// 158263508Sdim/// @param path Set to \a path + [\a begin, \a end). 159263508Sdim/// @param begin Start of components to append. 160263508Sdim/// @param end One past the end of components to append. 161263508Sdimvoid append(SmallVectorImpl<char> &path, 162263508Sdim const_iterator begin, const_iterator end); 163263508Sdim 164263508Sdim/// @} 165263508Sdim/// @name Transforms (or some other better name) 166263508Sdim/// @{ 167263508Sdim 168263508Sdim/// Convert path to the native form. This is used to give paths to users and 169263508Sdim/// operating system calls in the platform's normal way. For example, on Windows 170263508Sdim/// all '/' are converted to '\'. 171263508Sdim/// 172263508Sdim/// @param path A path that is transformed to native format. 173263508Sdim/// @param result Holds the result of the transformation. 174263508Sdimvoid native(const Twine &path, SmallVectorImpl<char> &result); 175263508Sdim 176263508Sdim/// Convert path to the native form in place. This is used to give paths to 177263508Sdim/// users and operating system calls in the platform's normal way. For example, 178263508Sdim/// on Windows all '/' are converted to '\'. 179263508Sdim/// 180263508Sdim/// @param path A path that is transformed to native format. 181263508Sdimvoid native(SmallVectorImpl<char> &path); 182263508Sdim 183263508Sdim/// @} 184263508Sdim/// @name Lexical Observers 185263508Sdim/// @{ 186263508Sdim 187263508Sdim/// @brief Get root name. 188263508Sdim/// 189263508Sdim/// @code 190263508Sdim/// //net/hello => //net 191263508Sdim/// c:/hello => c: (on Windows, on other platforms nothing) 192263508Sdim/// /hello => <empty> 193263508Sdim/// @endcode 194263508Sdim/// 195263508Sdim/// @param path Input path. 196263508Sdim/// @result The root name of \a path if it has one, otherwise "". 197263508Sdimconst StringRef root_name(StringRef path); 198263508Sdim 199263508Sdim/// @brief Get root directory. 200263508Sdim/// 201263508Sdim/// @code 202263508Sdim/// /goo/hello => / 203263508Sdim/// c:/hello => / 204263508Sdim/// d/file.txt => <empty> 205263508Sdim/// @endcode 206263508Sdim/// 207263508Sdim/// @param path Input path. 208263508Sdim/// @result The root directory of \a path if it has one, otherwise 209263508Sdim/// "". 210263508Sdimconst StringRef root_directory(StringRef path); 211263508Sdim 212263508Sdim/// @brief Get root path. 213263508Sdim/// 214263508Sdim/// Equivalent to root_name + root_directory. 215263508Sdim/// 216263508Sdim/// @param path Input path. 217263508Sdim/// @result The root path of \a path if it has one, otherwise "". 218263508Sdimconst StringRef root_path(StringRef path); 219263508Sdim 220263508Sdim/// @brief Get relative path. 221263508Sdim/// 222263508Sdim/// @code 223263508Sdim/// C:\hello\world => hello\world 224263508Sdim/// foo/bar => foo/bar 225263508Sdim/// /foo/bar => foo/bar 226263508Sdim/// @endcode 227263508Sdim/// 228263508Sdim/// @param path Input path. 229263508Sdim/// @result The path starting after root_path if one exists, otherwise "". 230263508Sdimconst StringRef relative_path(StringRef path); 231263508Sdim 232263508Sdim/// @brief Get parent path. 233263508Sdim/// 234263508Sdim/// @code 235263508Sdim/// / => <empty> 236263508Sdim/// /foo => / 237263508Sdim/// foo/../bar => foo/.. 238263508Sdim/// @endcode 239263508Sdim/// 240263508Sdim/// @param path Input path. 241263508Sdim/// @result The parent path of \a path if one exists, otherwise "". 242263508Sdimconst StringRef parent_path(StringRef path); 243263508Sdim 244263508Sdim/// @brief Get filename. 245263508Sdim/// 246263508Sdim/// @code 247263508Sdim/// /foo.txt => foo.txt 248263508Sdim/// . => . 249263508Sdim/// .. => .. 250263508Sdim/// / => / 251263508Sdim/// @endcode 252263508Sdim/// 253263508Sdim/// @param path Input path. 254263508Sdim/// @result The filename part of \a path. This is defined as the last component 255263508Sdim/// of \a path. 256263508Sdimconst StringRef filename(StringRef path); 257263508Sdim 258263508Sdim/// @brief Get stem. 259263508Sdim/// 260263508Sdim/// If filename contains a dot but not solely one or two dots, result is the 261263508Sdim/// substring of filename ending at (but not including) the last dot. Otherwise 262263508Sdim/// it is filename. 263263508Sdim/// 264263508Sdim/// @code 265263508Sdim/// /foo/bar.txt => bar 266263508Sdim/// /foo/bar => bar 267263508Sdim/// /foo/.txt => <empty> 268263508Sdim/// /foo/. => . 269263508Sdim/// /foo/.. => .. 270263508Sdim/// @endcode 271263508Sdim/// 272263508Sdim/// @param path Input path. 273263508Sdim/// @result The stem of \a path. 274263508Sdimconst StringRef stem(StringRef path); 275263508Sdim 276263508Sdim/// @brief Get extension. 277263508Sdim/// 278263508Sdim/// If filename contains a dot but not solely one or two dots, result is the 279263508Sdim/// substring of filename starting at (and including) the last dot, and ending 280263508Sdim/// at the end of \a path. Otherwise "". 281263508Sdim/// 282263508Sdim/// @code 283263508Sdim/// /foo/bar.txt => .txt 284263508Sdim/// /foo/bar => <empty> 285263508Sdim/// /foo/.txt => .txt 286263508Sdim/// @endcode 287263508Sdim/// 288263508Sdim/// @param path Input path. 289263508Sdim/// @result The extension of \a path. 290263508Sdimconst StringRef extension(StringRef path); 291263508Sdim 292263508Sdim/// @brief Check whether the given char is a path separator on the host OS. 293263508Sdim/// 294263508Sdim/// @param value a character 295263508Sdim/// @result true if \a value is a path separator character on the host OS 296263508Sdimbool is_separator(char value); 297263508Sdim 298263508Sdim/// @brief Get the typical temporary directory for the system, e.g., 299263508Sdim/// "/var/tmp" or "C:/TEMP" 300263508Sdim/// 301263508Sdim/// @param erasedOnReboot Whether to favor a path that is erased on reboot 302263508Sdim/// rather than one that potentially persists longer. This parameter will be 303263508Sdim/// ignored if the user or system has set the typical environment variable 304263508Sdim/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. 305263508Sdim/// 306263508Sdim/// @param result Holds the resulting path name. 307263508Sdimvoid system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); 308263508Sdim 309263508Sdim/// @brief Has root name? 310263508Sdim/// 311263508Sdim/// root_name != "" 312263508Sdim/// 313263508Sdim/// @param path Input path. 314263508Sdim/// @result True if the path has a root name, false otherwise. 315263508Sdimbool has_root_name(const Twine &path); 316263508Sdim 317263508Sdim/// @brief Has root directory? 318263508Sdim/// 319263508Sdim/// root_directory != "" 320263508Sdim/// 321263508Sdim/// @param path Input path. 322263508Sdim/// @result True if the path has a root directory, false otherwise. 323263508Sdimbool has_root_directory(const Twine &path); 324263508Sdim 325263508Sdim/// @brief Has root path? 326263508Sdim/// 327263508Sdim/// root_path != "" 328263508Sdim/// 329263508Sdim/// @param path Input path. 330263508Sdim/// @result True if the path has a root path, false otherwise. 331263508Sdimbool has_root_path(const Twine &path); 332263508Sdim 333263508Sdim/// @brief Has relative path? 334263508Sdim/// 335263508Sdim/// relative_path != "" 336263508Sdim/// 337263508Sdim/// @param path Input path. 338263508Sdim/// @result True if the path has a relative path, false otherwise. 339263508Sdimbool has_relative_path(const Twine &path); 340263508Sdim 341263508Sdim/// @brief Has parent path? 342263508Sdim/// 343263508Sdim/// parent_path != "" 344263508Sdim/// 345263508Sdim/// @param path Input path. 346263508Sdim/// @result True if the path has a parent path, false otherwise. 347263508Sdimbool has_parent_path(const Twine &path); 348263508Sdim 349263508Sdim/// @brief Has filename? 350263508Sdim/// 351263508Sdim/// filename != "" 352263508Sdim/// 353263508Sdim/// @param path Input path. 354263508Sdim/// @result True if the path has a filename, false otherwise. 355263508Sdimbool has_filename(const Twine &path); 356263508Sdim 357263508Sdim/// @brief Has stem? 358263508Sdim/// 359263508Sdim/// stem != "" 360263508Sdim/// 361263508Sdim/// @param path Input path. 362263508Sdim/// @result True if the path has a stem, false otherwise. 363263508Sdimbool has_stem(const Twine &path); 364263508Sdim 365263508Sdim/// @brief Has extension? 366263508Sdim/// 367263508Sdim/// extension != "" 368263508Sdim/// 369263508Sdim/// @param path Input path. 370263508Sdim/// @result True if the path has a extension, false otherwise. 371263508Sdimbool has_extension(const Twine &path); 372263508Sdim 373263508Sdim/// @brief Is path absolute? 374263508Sdim/// 375263508Sdim/// @param path Input path. 376263508Sdim/// @result True if the path is absolute, false if it is not. 377263508Sdimbool is_absolute(const Twine &path); 378263508Sdim 379263508Sdim/// @brief Is path relative? 380263508Sdim/// 381263508Sdim/// @param path Input path. 382263508Sdim/// @result True if the path is relative, false if it is not. 383263508Sdimbool is_relative(const Twine &path); 384263508Sdim 385263508Sdim} // end namespace path 386263508Sdim} // end namespace sys 387263508Sdim} // end namespace llvm 388263508Sdim 389263508Sdim#endif 390