Path.cpp revision 40db5d4539144aa086b60685a4dae324972fb23f
1b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===// 2f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 3b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// The LLVM Compiler Infrastructure 4b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 8b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===// 9b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// 10b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// This header file implements the operating system Path concept. 11b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// 12b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===// 138e66595512b065b69d595bae665b6ad665eca6d0Reid Spencer 14b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer#include "llvm/System/Path.h" 1579fc9249574cee0ec69d920e5a16497ba799020aReid Spencer#include "llvm/Config/config.h" 1698bc8ed49be09c282e2f0f679fcce382f62390dcAlkis Evlogimenos#include <cassert> 17f52e32aab0422407cc8def93348667c255bb5d80Duncan Sands#include <cstring> 18c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattner#include <ostream> 19c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattnerusing namespace llvm; 208e66595512b065b69d595bae665b6ad665eca6d0Reid Spencerusing namespace sys; 21b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer 22b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===// 23b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//=== WARNING: Implementation here must contain only TRULY operating system 24f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman//=== independent code. 25b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===// 26b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer 2740db5d4539144aa086b60685a4dae324972fb23fBill Wendlingbool Path::operator==(const Path &that) const { 2840db5d4539144aa086b60685a4dae324972fb23fBill Wendling return path == that.path; 2940db5d4539144aa086b60685a4dae324972fb23fBill Wendling} 3040db5d4539144aa086b60685a4dae324972fb23fBill Wendling 3140db5d4539144aa086b60685a4dae324972fb23fBill Wendlingbool Path::operator!=(const Path &that) const { 3240db5d4539144aa086b60685a4dae324972fb23fBill Wendling return path != that.path; 3340db5d4539144aa086b60685a4dae324972fb23fBill Wendling} 3440db5d4539144aa086b60685a4dae324972fb23fBill Wendling 3540db5d4539144aa086b60685a4dae324972fb23fBill Wendlingbool Path::operator<(const Path& that) const { 3640db5d4539144aa086b60685a4dae324972fb23fBill Wendling return path < that.path; 3740db5d4539144aa086b60685a4dae324972fb23fBill Wendling} 3840db5d4539144aa086b60685a4dae324972fb23fBill Wendling 39c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattnerstd::ostream& llvm::operator<<(std::ostream &strm, const sys::Path &aPath) { 40c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattner strm << aPath.toString(); 41c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattner return strm; 42c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattner} 43c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattner 44c29befb554c025da801737bc86a8215d1dc6038cReid SpencerPath 45c29befb554c025da801737bc86a8215d1dc6038cReid SpencerPath::GetLLVMConfigDir() { 46c29befb554c025da801737bc86a8215d1dc6038cReid Spencer Path result; 47ab68df02bc29045b9f02783518fbc7d0f23f56b7Jeff Cohen#ifdef LLVM_ETCDIR 48dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer if (result.set(LLVM_ETCDIR)) 49c29befb554c025da801737bc86a8215d1dc6038cReid Spencer return result; 50ab68df02bc29045b9f02783518fbc7d0f23f56b7Jeff Cohen#endif 51c29befb554c025da801737bc86a8215d1dc6038cReid Spencer return GetLLVMDefaultConfigDir(); 52c29befb554c025da801737bc86a8215d1dc6038cReid Spencer} 53c29befb554c025da801737bc86a8215d1dc6038cReid Spencer 54f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha BrukmanLLVMFileType 55a2a62210f2b5fb69364c62e65bb0b8baae6cc50eReid Spencersys::IdentifyFileType(const char*magic, unsigned length) { 56f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer assert(magic && "Invalid magic number string"); 57f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer assert(length >=4 && "Invalid magic number length"); 58f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer switch (magic[0]) { 59f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner case 'B': 60f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE) 61f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner return Bitcode_FileType; 62f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner break; 63f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer case '!': 648bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer if (length >= 8) 65f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer if (memcmp(magic,"!<arch>\n",8) == 0) 668bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer return Archive_FileType; 678bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer break; 688bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer 698bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case '\177': 7024eac6cb00ab18afe7a175ea876bbde776c07532Chris Lattner if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') { 71947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer if (length >= 18 && magic[17] == 0) 72947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer switch (magic[16]) { 73947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer default: break; 74947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 1: return ELF_Relocatable_FileType; 75947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 2: return ELF_Executable_FileType; 76947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 3: return ELF_SharedObject_FileType; 77947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 4: return ELF_Core_FileType; 78947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer } 7924eac6cb00ab18afe7a175ea876bbde776c07532Chris Lattner } 808bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer break; 818bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer 82ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner case 0xCA: 838bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer // This is complicated by an overlap with Java class files. 848bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer // See the Mach-O section in /usr/share/file/magic for details. 85ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner if (magic[1] == char(0xFE) && magic[2] == char(0xBA) && 86ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner magic[3] == char(0xBE)) { 87ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner return Mach_O_DynamicallyLinkedSharedLib_FileType; 88ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner 89ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner // FIXME: How does this work? 90947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer if (length >= 14 && magic[13] == 0) 91947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer switch (magic[12]) { 92947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer default: break; 93947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 1: return Mach_O_Object_FileType; 94947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 2: return Mach_O_Executable_FileType; 95947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType; 96947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 4: return Mach_O_Core_FileType; 97947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 5: return Mach_O_PreloadExectuable_FileType; 98947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType; 99947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 7: return Mach_O_DynamicLinker_FileType; 100947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 8: return Mach_O_Bundle_FileType; 101947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType; 102947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer } 103ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner } 1048bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer break; 1058bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer 1068bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0xF0: // PowerPC Windows 1078bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x83: // Alpha 32-bit 1088bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x84: // Alpha 64-bit 1098bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x66: // MPS R4000 Windows 1108bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x50: // mc68K 1118bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x4c: // 80386 Windows 1128bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer if (magic[1] == 0x01) 1138bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer return COFF_FileType; 1148bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer 1158bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x90: // PA-RISC Windows 1168bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer case 0x68: // mc68K Windows 1178bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer if (magic[1] == 0x02) 1188bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer return COFF_FileType; 119f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer break; 120f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer 121f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer default: 122f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer break; 123f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer } 1248bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer return Unknown_FileType; 125f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer} 126f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer 127ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencerbool 128ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath::isArchive() const { 129c7f083297cd796c2fadb534307e4ef406fd68945Reid Spencer if (canRead()) 130ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer return hasMagicNumber("!<arch>\012"); 131ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer return false; 132ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer} 133ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer 134ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencerbool 135ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath::isDynamicLibrary() const { 136410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer if (canRead()) { 137410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer std::string Magic; 138410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer if (getMagicNumber(Magic, 64)) 13934cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng switch (IdentifyFileType(Magic.c_str(), 14034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng static_cast<unsigned>(Magic.length()))) { 141410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer default: return false; 142947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case Mach_O_FixedVirtualMemorySharedLib_FileType: 143947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case Mach_O_DynamicallyLinkedSharedLib_FileType: 144947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case Mach_O_DynamicallyLinkedSharedLibStub_FileType: 145947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer case ELF_SharedObject_FileType: 146410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer case COFF_FileType: return true; 147410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer } 148410aa020a2c834a5029bb98ee44691c0ec6f2c53Reid Spencer } 149ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer return false; 150ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer} 151ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer 152ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath 153ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath::FindLibrary(std::string& name) { 154ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer std::vector<sys::Path> LibPaths; 155ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer GetSystemLibraryPaths(LibPaths); 156ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer for (unsigned i = 0; i < LibPaths.size(); ++i) { 157ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer sys::Path FullPath(LibPaths[i]); 158dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT); 159ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer if (FullPath.isDynamicLibrary()) 160ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer return FullPath; 161dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer FullPath.eraseSuffix(); 162ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer FullPath.appendSuffix("a"); 163ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer if (FullPath.isArchive()) 164ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer return FullPath; 165ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer } 166ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer return sys::Path(); 167ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer} 168ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer 169c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattnerstd::string Path::GetDLLSuffix() { 17079fc9249574cee0ec69d920e5a16497ba799020aReid Spencer return LTDL_SHLIB_EXT; 17179fc9249574cee0ec69d920e5a16497ba799020aReid Spencer} 17279fc9249574cee0ec69d920e5a16497ba799020aReid Spencer 173f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattnerbool 174f283a5e53a99d13035a9e783acff80d4ea064a92Chris LattnerPath::isBitcodeFile() const { 175f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner std::string actualMagic; 176f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner if (!getMagicNumber(actualMagic, 4)) 177f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner return false; 178f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner return actualMagic == "BC\xC0\xDE"; 179f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner} 180f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner 181f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattnerbool Path::hasMagicNumber(const std::string &Magic) const { 182f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner std::string actualMagic; 18334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng if (getMagicNumber(actualMagic, static_cast<unsigned>(Magic.size()))) 184f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner return Magic == actualMagic; 185f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner return false; 186f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner} 187f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner 188e18bc08fbc674584fe3a3a0c6b866a5aea201a91Anton Korobeynikovstd::string 189e18bc08fbc674584fe3a3a0c6b866a5aea201a91Anton KorobeynikovPath::getSuffix() const { 190e18bc08fbc674584fe3a3a0c6b866a5aea201a91Anton Korobeynikov return path.substr(path.rfind('.') + 1); 191e18bc08fbc674584fe3a3a0c6b866a5aea201a91Anton Korobeynikov} 192f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner 193e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattnerstatic void getPathList(const char*path, std::vector<Path>& Paths) { 194e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner const char* at = path; 195e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner const char* delim = strchr(at, PathSeparator); 196e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner Path tmpPath; 197e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner while (delim != 0) { 198e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner std::string tmp(at, size_t(delim-at)); 199e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner if (tmpPath.set(tmp)) 200e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner if (tmpPath.canRead()) 201e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner Paths.push_back(tmpPath); 202e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner at = delim + 1; 203e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner delim = strchr(at, PathSeparator); 204e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner } 205e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner 206e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner if (*at != 0) 207e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner if (tmpPath.set(std::string(at))) 208e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner if (tmpPath.canRead()) 209e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner Paths.push_back(tmpPath); 210e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner} 211e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner 2129b01cc0ede3bfef32ce46159670dedc3e9769a64Ted Kremenekstatic std::string getDirnameCharSep(const std::string& path, char Sep) { 213cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 214cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek if (path.empty()) 215cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek return "."; 216cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 217cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek // If the path is all slashes, return a single slash. 218cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek // Otherwise, remove all trailing slashes. 219cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 22034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng signed pos = static_cast<signed>(path.size()) - 1; 221cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 222cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek while (pos >= 0 && path[pos] == Sep) 223cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek --pos; 224cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 225cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek if (pos < 0) 226cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek return path[0] == Sep ? std::string(1, Sep) : std::string("."); 227cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 228cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek // Any slashes left? 229cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek signed i = 0; 230cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 231cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek while (i < pos && path[i] != Sep) 232cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek ++i; 233cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 234cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek if (i == pos) // No slashes? Return "." 235cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek return "."; 236cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 237cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek // There is at least one slash left. Remove all trailing non-slashes. 238cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek while (pos >= 0 && path[pos] != Sep) 239cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek --pos; 240cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 241cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek // Remove any trailing slashes. 242cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek while (pos >= 0 && path[pos] == Sep) 243cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek --pos; 244cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 245cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek if (pos < 0) 246cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek return path[0] == Sep ? std::string(1, Sep) : std::string("."); 247cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 248cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek return path.substr(0, pos+1); 249cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek} 250cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek 251b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// Include the truly platform-specific parts of this class. 252dafe55f64b038445adce31fe884e453db859194cReid Spencer#if defined(LLVM_ON_UNIX) 253bccc8abc79338d1cfdd5ea20f7288452ddf75b84Reid Spencer#include "Unix/Path.inc" 254dafe55f64b038445adce31fe884e453db859194cReid Spencer#endif 255dafe55f64b038445adce31fe884e453db859194cReid Spencer#if defined(LLVM_ON_WIN32) 256bccc8abc79338d1cfdd5ea20f7288452ddf75b84Reid Spencer#include "Win32/Path.inc" 257dafe55f64b038445adce31fe884e453db859194cReid Spencer#endif 25823dd3327a03b9b64b428ea07dae580326159e47bReid Spencer 259