diff options
Diffstat (limited to 'contrib/llvm/lib/Support')
| -rw-r--r-- | contrib/llvm/lib/Support/CommandLine.cpp | 2 | ||||
| -rw-r--r-- | contrib/llvm/lib/Support/Path.cpp | 10 | ||||
| -rw-r--r-- | contrib/llvm/lib/Support/TarWriter.cpp | 42 | 
3 files changed, 41 insertions, 13 deletions
| diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp index 0a989706b436..3889902eea54 100644 --- a/contrib/llvm/lib/Support/CommandLine.cpp +++ b/contrib/llvm/lib/Support/CommandLine.cpp @@ -373,7 +373,7 @@ void Option::removeArgument() { GlobalParser->removeOption(this); }  void Option::setArgStr(StringRef S) {    if (FullyInitialized)      GlobalParser->updateArgStr(this, S); -  assert(S[0] != '-' && "Option can't start with '-"); +  assert((S.empty() || S[0] != '-') && "Option can't start with '-");    ArgStr = S;  } diff --git a/contrib/llvm/lib/Support/Path.cpp b/contrib/llvm/lib/Support/Path.cpp index 0616d05aff57..4bb035eeccca 100644 --- a/contrib/llvm/lib/Support/Path.cpp +++ b/contrib/llvm/lib/Support/Path.cpp @@ -571,6 +571,16 @@ void native(SmallVectorImpl<char> &Path) {  #endif  } +std::string convert_to_slash(StringRef path) { +#ifdef LLVM_ON_WIN32 +  std::string s = path.str(); +  std::replace(s.begin(), s.end(), '\\', '/'); +  return s; +#else +  return path; +#endif +} +  StringRef filename(StringRef path) {    return *rbegin(path);  } diff --git a/contrib/llvm/lib/Support/TarWriter.cpp b/contrib/llvm/lib/Support/TarWriter.cpp index 5fc17d276377..f79b364dc1f7 100644 --- a/contrib/llvm/lib/Support/TarWriter.cpp +++ b/contrib/llvm/lib/Support/TarWriter.cpp @@ -26,6 +26,7 @@  #include "llvm/ADT/StringRef.h"  #include "llvm/Support/FileSystem.h"  #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Path.h"  using namespace llvm; @@ -109,27 +110,44 @@ static void writePaxHeader(raw_fd_ostream &OS, StringRef Path) {    pad(OS);  } +// In the Ustar header, a path can be split at any '/' to store +// a path into UstarHeader::Name and UstarHeader::Prefix. This +// function splits a given path for that purpose. +static std::pair<StringRef, StringRef> splitPath(StringRef Path) { +  if (Path.size() <= sizeof(UstarHeader::Name)) +    return {"", Path}; +  size_t Sep = Path.rfind('/', sizeof(UstarHeader::Name) + 1); +  if (Sep == StringRef::npos) +    return {"", Path}; +  return {Path.substr(0, Sep), Path.substr(Sep + 1)}; +} + +// Returns true if a given path can be stored to a Ustar header +// without the PAX extension. +static bool fitsInUstar(StringRef Path) { +  StringRef Prefix; +  StringRef Name; +  std::tie(Prefix, Name) = splitPath(Path); +  return Name.size() <= sizeof(UstarHeader::Name); +} +  // The PAX header is an extended format, so a PAX header needs  // to be followed by a "real" header.  static void writeUstarHeader(raw_fd_ostream &OS, StringRef Path, size_t Size) { +  StringRef Prefix; +  StringRef Name; +  std::tie(Prefix, Name) = splitPath(Path); +    UstarHeader Hdr = {}; -  memcpy(Hdr.Name, Path.data(), Path.size()); +  memcpy(Hdr.Name, Name.data(), Name.size());    memcpy(Hdr.Mode, "0000664", 8);    snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", Size);    memcpy(Hdr.Magic, "ustar", 6); +  memcpy(Hdr.Prefix, Prefix.data(), Prefix.size());    computeChecksum(Hdr);    OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));  } -// We want to use '/' as a path separator even on Windows. -// This function canonicalizes a given path. -static std::string canonicalize(std::string S) { -#ifdef LLVM_ON_WIN32 -  std::replace(S.begin(), S.end(), '\\', '/'); -#endif -  return S; -} -  // Creates a TarWriter instance and returns it.  Expected<std::unique_ptr<TarWriter>> TarWriter::create(StringRef OutputPath,                                                         StringRef BaseDir) { @@ -145,8 +163,8 @@ TarWriter::TarWriter(int FD, StringRef BaseDir)  // Append a given file to an archive.  void TarWriter::append(StringRef Path, StringRef Data) {    // Write Path and Data. -  std::string S = BaseDir + "/" + canonicalize(Path) + "\0"; -  if (S.size() <= sizeof(UstarHeader::Name)) { +  std::string S = BaseDir + "/" + sys::path::convert_to_slash(Path) + "\0"; +  if (fitsInUstar(S)) {      writeUstarHeader(OS, S, Data.size());    } else {      writePaxHeader(OS, S); | 
