jjm::Utf8String jjm::Path::getFileName() const { Utf8String result; pair<size_t, size_t> const lastComponent = getPrevComponent(path, path.size()); result.append(path.data() + lastComponent.first, path.data() + lastComponent.second); return result; }
jjm::Path jjm::Path::getAbsolutePath() const { #ifdef _WIN32 if (isEmpty()) return *this; pair<size_t, size_t> prefix = ::getPrefix(path); bool const hasPrefix = prefix.first != prefix.second; bool const isAbs = isAbsolute(); if (hasPrefix && isAbs) return *this; Utf8String root; if (hasPrefix) root.append(path.data() + prefix.first, path.data() + prefix.second); if (isAbs) root.push_back(preferredSeparator); else root.push_back('.'); Utf8String root2 = invokeGetFullPathW(root); Path root3(root2); Path result = resolve(root3); pair<size_t, size_t> resultPrefix = ::getPrefix(result.path); if (resultPrefix.first == resultPrefix.second) JFATAL(0, path); if ( ! result.isAbsolute()) JFATAL(0, path); if (result.isRootPath()) return result; vector<pair<size_t, size_t> > components; for (pair<size_t, size_t> component(resultPrefix.second, resultPrefix.second); ; ) { component = ::getNextComponent(result.path, component.second); if (component.first == component.second) break; if (1 == component.second - component.first && result.path.data()[component.first] == '.') continue; components.push_back(component); } for (size_t i = 0; i < components.size(); ) { if (2 == components[i].second - components[i].first && result.path.data()[components[i].first] == '.' && result.path.data()[components[i].first + 1] == '.') { if (i == 0) return Path(); components.erase(components.begin() + i - 1, components.begin() + i + 1); --i; }else { ++i; } } Path result2; result2.path.append(result.path.data() + resultPrefix.first, result.path.data() + resultPrefix.second); if (components.size() == 0) result2.path.push_back(preferredSeparator); for (size_t i = 0; i < components.size(); ++i) { result2.path.push_back(preferredSeparator); result2.path.append(result.path.data() + components[i].first, result.path.data() + components[i].second); } return result2; #else if (isEmpty()) return *this; pair<size_t, size_t> prefix = ::getPrefix(path); if (prefix.first != prefix.second) throw std::runtime_error("jjm::Path::makeAbsolute() on POSIX systems does not support prefixes"); if (isAbsolute() == false) { errno = 0; UniquePtr<char*, jjm::InvokeFree> currentWorkingDirectory(::getcwd(0, 0)); int const lastErrno = errno; if (currentWorkingDirectory.get() == 0) { string msg = string() + "jjm::Path::getAbsolutePath() failed. " + "::getcwd(0, 0) failed. "; //TODO throw runtime_error(msg + "errno " + toDecStr(lastErrno) + " " + getErrnoName(lastErrno) + "."); throw runtime_error(msg + "errno " + toDecStr(lastErrno) + "."); } return resolve(Path(currentWorkingDirectory.get())); } return *this; #endif }