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// 10263509Sdim// This file declares the llvm::sys::path namespace. It is designed after 11263509Sdim// TR2/boost filesystem (v3), but modified to remove exception handling and the 12263509Sdim// path class. 13218885Sdim// 14218885Sdim//===----------------------------------------------------------------------===// 15218885Sdim 16263509Sdim#ifndef LLVM_SUPPORT_PATH_H 17263509Sdim#define LLVM_SUPPORT_PATH_H 18263509Sdim 19263509Sdim#include "llvm/ADT/SmallString.h" 20263509Sdim#include "llvm/ADT/Twine.h" 21263509Sdim#include "llvm/Support/DataTypes.h" 22263509Sdim#include <iterator> 23263509Sdim 24263509Sdimnamespace llvm { 25263509Sdimnamespace sys { 26263509Sdimnamespace path { 27263509Sdim 28263509Sdim/// @name Lexical Component Iterator 29263509Sdim/// @{ 30263509Sdim 31263509Sdim/// @brief Path iterator. 32263509Sdim/// 33263509Sdim/// This is a bidirectional iterator that iterates over the individual 34263509Sdim/// components in \a path. The forward traversal order is as follows: 35263509Sdim/// * The root-name element, if present. 36263509Sdim/// * The root-directory element, if present. 37263509Sdim/// * Each successive filename element, if present. 38263509Sdim/// * Dot, if one or more trailing non-root slash characters are present. 39263509Sdim/// The backwards traversal order is the reverse of forward traversal. 40263509Sdim/// 41263509Sdim/// Iteration examples. Each component is separated by ',': 42263509Sdim/// @code 43263509Sdim/// / => / 44263509Sdim/// /foo => /,foo 45263509Sdim/// foo/ => foo,. 46263509Sdim/// /foo/bar => /,foo,bar 47263509Sdim/// ../ => ..,. 48263509Sdim/// C:\foo\bar => C:,/,foo,bar 49263509Sdim/// @endcode 50263509Sdimclass const_iterator { 51263509Sdim StringRef Path; ///< The entire path. 52263509Sdim StringRef Component; ///< The current component. Not necessarily in Path. 53263509Sdim size_t Position; ///< The iterators current position within Path. 54263509Sdim 55263509Sdim // An end iterator has Position = Path.size() + 1. 56263509Sdim friend const_iterator begin(StringRef path); 57263509Sdim friend const_iterator end(StringRef path); 58263509Sdim 59263509Sdimpublic: 60263509Sdim typedef const StringRef value_type; 61263509Sdim typedef ptrdiff_t difference_type; 62263509Sdim typedef value_type &reference; 63263509Sdim typedef value_type *pointer; 64263509Sdim typedef std::bidirectional_iterator_tag iterator_category; 65263509Sdim 66263509Sdim reference operator*() const { return Component; } 67263509Sdim pointer operator->() const { return &Component; } 68263509Sdim const_iterator &operator++(); // preincrement 69263509Sdim const_iterator &operator++(int); // postincrement 70263509Sdim const_iterator &operator--(); // predecrement 71263509Sdim const_iterator &operator--(int); // postdecrement 72263509Sdim bool operator==(const const_iterator &RHS) const; 73263509Sdim bool operator!=(const const_iterator &RHS) const; 74263509Sdim 75263509Sdim /// @brief Difference in bytes between this and RHS. 76263509Sdim ptrdiff_t operator-(const const_iterator &RHS) const; 77263509Sdim}; 78263509Sdim 79263509Sdimtypedef std::reverse_iterator<const_iterator> reverse_iterator; 80263509Sdim 81263509Sdim/// @brief Get begin iterator over \a path. 82263509Sdim/// @param path Input path. 83263509Sdim/// @returns Iterator initialized with the first component of \a path. 84263509Sdimconst_iterator begin(StringRef path); 85263509Sdim 86263509Sdim/// @brief Get end iterator over \a path. 87263509Sdim/// @param path Input path. 88263509Sdim/// @returns Iterator initialized to the end of \a path. 89263509Sdimconst_iterator end(StringRef path); 90263509Sdim 91263509Sdim/// @brief Get reverse begin iterator over \a path. 92263509Sdim/// @param path Input path. 93263509Sdim/// @returns Iterator initialized with the first reverse component of \a path. 94263509Sdiminline reverse_iterator rbegin(StringRef path) { 95263509Sdim return reverse_iterator(end(path)); 96263509Sdim} 97263509Sdim 98263509Sdim/// @brief Get reverse end iterator over \a path. 99263509Sdim/// @param path Input path. 100263509Sdim/// @returns Iterator initialized to the reverse end of \a path. 101263509Sdiminline reverse_iterator rend(StringRef path) { 102263509Sdim return reverse_iterator(begin(path)); 103263509Sdim} 104263509Sdim 105263509Sdim/// @} 106263509Sdim/// @name Lexical Modifiers 107263509Sdim/// @{ 108263509Sdim 109263509Sdim/// @brief Remove the last component from \a path unless it is the root dir. 110263509Sdim/// 111263509Sdim/// @code 112263509Sdim/// directory/filename.cpp => directory/ 113263509Sdim/// directory/ => directory 114263509Sdim/// filename.cpp => <empty> 115263509Sdim/// / => / 116263509Sdim/// @endcode 117263509Sdim/// 118263509Sdim/// @param path A path that is modified to not have a file component. 119263509Sdimvoid remove_filename(SmallVectorImpl<char> &path); 120263509Sdim 121263509Sdim/// @brief Replace the file extension of \a path with \a extension. 122263509Sdim/// 123263509Sdim/// @code 124263509Sdim/// ./filename.cpp => ./filename.extension 125263509Sdim/// ./filename => ./filename.extension 126263509Sdim/// ./ => ./.extension 127263509Sdim/// @endcode 128263509Sdim/// 129263509Sdim/// @param path A path that has its extension replaced with \a extension. 130263509Sdim/// @param extension The extension to be added. It may be empty. It may also 131263509Sdim/// optionally start with a '.', if it does not, one will be 132263509Sdim/// prepended. 133263509Sdimvoid replace_extension(SmallVectorImpl<char> &path, const Twine &extension); 134263509Sdim 135263509Sdim/// @brief Append to path. 136263509Sdim/// 137263509Sdim/// @code 138263509Sdim/// /foo + bar/f => /foo/bar/f 139263509Sdim/// /foo/ + bar/f => /foo/bar/f 140263509Sdim/// foo + bar/f => foo/bar/f 141263509Sdim/// @endcode 142263509Sdim/// 143263509Sdim/// @param path Set to \a path + \a component. 144263509Sdim/// @param a The component to be appended to \a path. 145263509Sdimvoid append(SmallVectorImpl<char> &path, const Twine &a, 146263509Sdim const Twine &b = "", 147263509Sdim const Twine &c = "", 148263509Sdim const Twine &d = ""); 149263509Sdim 150263509Sdim/// @brief Append to path. 151263509Sdim/// 152263509Sdim/// @code 153263509Sdim/// /foo + [bar,f] => /foo/bar/f 154263509Sdim/// /foo/ + [bar,f] => /foo/bar/f 155263509Sdim/// foo + [bar,f] => foo/bar/f 156263509Sdim/// @endcode 157263509Sdim/// 158263509Sdim/// @param path Set to \a path + [\a begin, \a end). 159263509Sdim/// @param begin Start of components to append. 160263509Sdim/// @param end One past the end of components to append. 161263509Sdimvoid append(SmallVectorImpl<char> &path, 162263509Sdim const_iterator begin, const_iterator end); 163263509Sdim 164263509Sdim/// @} 165263509Sdim/// @name Transforms (or some other better name) 166263509Sdim/// @{ 167263509Sdim 168263509Sdim/// Convert path to the native form. This is used to give paths to users and 169263509Sdim/// operating system calls in the platform's normal way. For example, on Windows 170263509Sdim/// all '/' are converted to '\'. 171263509Sdim/// 172263509Sdim/// @param path A path that is transformed to native format. 173263509Sdim/// @param result Holds the result of the transformation. 174263509Sdimvoid native(const Twine &path, SmallVectorImpl<char> &result); 175263509Sdim 176263509Sdim/// Convert path to the native form in place. This is used to give paths to 177263509Sdim/// users and operating system calls in the platform's normal way. For example, 178263509Sdim/// on Windows all '/' are converted to '\'. 179263509Sdim/// 180263509Sdim/// @param path A path that is transformed to native format. 181263509Sdimvoid native(SmallVectorImpl<char> &path); 182263509Sdim 183263509Sdim/// @} 184263509Sdim/// @name Lexical Observers 185263509Sdim/// @{ 186263509Sdim 187263509Sdim/// @brief Get root name. 188263509Sdim/// 189263509Sdim/// @code 190263509Sdim/// //net/hello => //net 191263509Sdim/// c:/hello => c: (on Windows, on other platforms nothing) 192263509Sdim/// /hello => <empty> 193263509Sdim/// @endcode 194263509Sdim/// 195263509Sdim/// @param path Input path. 196263509Sdim/// @result The root name of \a path if it has one, otherwise "". 197263509Sdimconst StringRef root_name(StringRef path); 198263509Sdim 199263509Sdim/// @brief Get root directory. 200263509Sdim/// 201263509Sdim/// @code 202263509Sdim/// /goo/hello => / 203263509Sdim/// c:/hello => / 204263509Sdim/// d/file.txt => <empty> 205263509Sdim/// @endcode 206263509Sdim/// 207263509Sdim/// @param path Input path. 208263509Sdim/// @result The root directory of \a path if it has one, otherwise 209263509Sdim/// "". 210263509Sdimconst StringRef root_directory(StringRef path); 211263509Sdim 212263509Sdim/// @brief Get root path. 213263509Sdim/// 214263509Sdim/// Equivalent to root_name + root_directory. 215263509Sdim/// 216263509Sdim/// @param path Input path. 217263509Sdim/// @result The root path of \a path if it has one, otherwise "". 218263509Sdimconst StringRef root_path(StringRef path); 219263509Sdim 220263509Sdim/// @brief Get relative path. 221263509Sdim/// 222263509Sdim/// @code 223263509Sdim/// C:\hello\world => hello\world 224263509Sdim/// foo/bar => foo/bar 225263509Sdim/// /foo/bar => foo/bar 226263509Sdim/// @endcode 227263509Sdim/// 228263509Sdim/// @param path Input path. 229263509Sdim/// @result The path starting after root_path if one exists, otherwise "". 230263509Sdimconst StringRef relative_path(StringRef path); 231263509Sdim 232263509Sdim/// @brief Get parent path. 233263509Sdim/// 234263509Sdim/// @code 235263509Sdim/// / => <empty> 236263509Sdim/// /foo => / 237263509Sdim/// foo/../bar => foo/.. 238263509Sdim/// @endcode 239263509Sdim/// 240263509Sdim/// @param path Input path. 241263509Sdim/// @result The parent path of \a path if one exists, otherwise "". 242263509Sdimconst StringRef parent_path(StringRef path); 243263509Sdim 244263509Sdim/// @brief Get filename. 245263509Sdim/// 246263509Sdim/// @code 247263509Sdim/// /foo.txt => foo.txt 248263509Sdim/// . => . 249263509Sdim/// .. => .. 250263509Sdim/// / => / 251263509Sdim/// @endcode 252263509Sdim/// 253263509Sdim/// @param path Input path. 254263509Sdim/// @result The filename part of \a path. This is defined as the last component 255263509Sdim/// of \a path. 256263509Sdimconst StringRef filename(StringRef path); 257263509Sdim 258263509Sdim/// @brief Get stem. 259263509Sdim/// 260263509Sdim/// If filename contains a dot but not solely one or two dots, result is the 261263509Sdim/// substring of filename ending at (but not including) the last dot. Otherwise 262263509Sdim/// it is filename. 263263509Sdim/// 264263509Sdim/// @code 265263509Sdim/// /foo/bar.txt => bar 266263509Sdim/// /foo/bar => bar 267263509Sdim/// /foo/.txt => <empty> 268263509Sdim/// /foo/. => . 269263509Sdim/// /foo/.. => .. 270263509Sdim/// @endcode 271263509Sdim/// 272263509Sdim/// @param path Input path. 273263509Sdim/// @result The stem of \a path. 274263509Sdimconst StringRef stem(StringRef path); 275263509Sdim 276263509Sdim/// @brief Get extension. 277263509Sdim/// 278263509Sdim/// If filename contains a dot but not solely one or two dots, result is the 279263509Sdim/// substring of filename starting at (and including) the last dot, and ending 280263509Sdim/// at the end of \a path. Otherwise "". 281263509Sdim/// 282263509Sdim/// @code 283263509Sdim/// /foo/bar.txt => .txt 284263509Sdim/// /foo/bar => <empty> 285263509Sdim/// /foo/.txt => .txt 286263509Sdim/// @endcode 287263509Sdim/// 288263509Sdim/// @param path Input path. 289263509Sdim/// @result The extension of \a path. 290263509Sdimconst StringRef extension(StringRef path); 291263509Sdim 292263509Sdim/// @brief Check whether the given char is a path separator on the host OS. 293263509Sdim/// 294263509Sdim/// @param value a character 295263509Sdim/// @result true if \a value is a path separator character on the host OS 296263509Sdimbool is_separator(char value); 297263509Sdim 298263509Sdim/// @brief Get the typical temporary directory for the system, e.g., 299263509Sdim/// "/var/tmp" or "C:/TEMP" 300263509Sdim/// 301263509Sdim/// @param erasedOnReboot Whether to favor a path that is erased on reboot 302263509Sdim/// rather than one that potentially persists longer. This parameter will be 303263509Sdim/// ignored if the user or system has set the typical environment variable 304263509Sdim/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. 305263509Sdim/// 306263509Sdim/// @param result Holds the resulting path name. 307263509Sdimvoid system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); 308263509Sdim 309263509Sdim/// @brief Has root name? 310263509Sdim/// 311263509Sdim/// root_name != "" 312263509Sdim/// 313263509Sdim/// @param path Input path. 314263509Sdim/// @result True if the path has a root name, false otherwise. 315263509Sdimbool has_root_name(const Twine &path); 316263509Sdim 317263509Sdim/// @brief Has root directory? 318263509Sdim/// 319263509Sdim/// root_directory != "" 320263509Sdim/// 321263509Sdim/// @param path Input path. 322263509Sdim/// @result True if the path has a root directory, false otherwise. 323263509Sdimbool has_root_directory(const Twine &path); 324263509Sdim 325263509Sdim/// @brief Has root path? 326263509Sdim/// 327263509Sdim/// root_path != "" 328263509Sdim/// 329263509Sdim/// @param path Input path. 330263509Sdim/// @result True if the path has a root path, false otherwise. 331263509Sdimbool has_root_path(const Twine &path); 332263509Sdim 333263509Sdim/// @brief Has relative path? 334263509Sdim/// 335263509Sdim/// relative_path != "" 336263509Sdim/// 337263509Sdim/// @param path Input path. 338263509Sdim/// @result True if the path has a relative path, false otherwise. 339263509Sdimbool has_relative_path(const Twine &path); 340263509Sdim 341263509Sdim/// @brief Has parent path? 342263509Sdim/// 343263509Sdim/// parent_path != "" 344263509Sdim/// 345263509Sdim/// @param path Input path. 346263509Sdim/// @result True if the path has a parent path, false otherwise. 347263509Sdimbool has_parent_path(const Twine &path); 348263509Sdim 349263509Sdim/// @brief Has filename? 350263509Sdim/// 351263509Sdim/// filename != "" 352263509Sdim/// 353263509Sdim/// @param path Input path. 354263509Sdim/// @result True if the path has a filename, false otherwise. 355263509Sdimbool has_filename(const Twine &path); 356263509Sdim 357263509Sdim/// @brief Has stem? 358263509Sdim/// 359263509Sdim/// stem != "" 360263509Sdim/// 361263509Sdim/// @param path Input path. 362263509Sdim/// @result True if the path has a stem, false otherwise. 363263509Sdimbool has_stem(const Twine &path); 364263509Sdim 365263509Sdim/// @brief Has extension? 366263509Sdim/// 367263509Sdim/// extension != "" 368263509Sdim/// 369263509Sdim/// @param path Input path. 370263509Sdim/// @result True if the path has a extension, false otherwise. 371263509Sdimbool has_extension(const Twine &path); 372263509Sdim 373263509Sdim/// @brief Is path absolute? 374263509Sdim/// 375263509Sdim/// @param path Input path. 376263509Sdim/// @result True if the path is absolute, false if it is not. 377263509Sdimbool is_absolute(const Twine &path); 378263509Sdim 379263509Sdim/// @brief Is path relative? 380263509Sdim/// 381263509Sdim/// @param path Input path. 382263509Sdim/// @result True if the path is relative, false if it is not. 383263509Sdimbool is_relative(const Twine &path); 384263509Sdim 385263509Sdim} // end namespace path 386263509Sdim} // end namespace sys 387263509Sdim} // end namespace llvm 388263509Sdim 389263509Sdim#endif 390