forked from OSchip/llvm-project
[llvm-ar] Accept file paths with windows format slashes
The internal representation of llvm-ar archives uses linux style slashes for paths, no matter the OS. In the case of windows this meant file paths input intending to match existing members would only match if linux style slashes where used. This change allows either slash direction to be input by the user. This change includes removing an unnecessary call to normalisePath and moving the call of another. Differential Revision: https://reviews.llvm.org/D65743 llvm-svn: 368573
This commit is contained in:
parent
fee242aed4
commit
47298393d2
|
@ -0,0 +1,44 @@
|
||||||
|
# Test that windows path seperators are handled correctly.
|
||||||
|
REQUIRES: system-windows
|
||||||
|
|
||||||
|
# Note: many of these tests depend on relative paths, so we have to cd to a
|
||||||
|
# test directory first.
|
||||||
|
RUN: mkdir -p %t && cd %t
|
||||||
|
RUN: rm -rf a b && mkdir a b
|
||||||
|
RUN: echo hello-a > a/foo.txt
|
||||||
|
RUN: echo hello-b > b/foo.txt
|
||||||
|
RUN: echo hello-parent > foo.txt
|
||||||
|
|
||||||
|
# P is implied when using thin archives.
|
||||||
|
# Create an archive.
|
||||||
|
RUN: rm -f archive.a
|
||||||
|
RUN: llvm-ar rcST archive.a a\..\a\foo.txt
|
||||||
|
RUN: llvm-ar rcST archive.a foo.txt
|
||||||
|
RUN: llvm-ar rcST archive.a b\foo.txt b/foo.txt
|
||||||
|
RUN: llvm-ar dT archive.a foo.txt
|
||||||
|
RUN: llvm-ar t archive.a | FileCheck %s --check-prefix=ARCHIVE --implicit-check-not {{.}}
|
||||||
|
|
||||||
|
ARCHIVE: a/foo.txt
|
||||||
|
ARCHIVE-NEXT: b/foo.txt
|
||||||
|
ARCHIVE-NEXT: b/foo.txt
|
||||||
|
|
||||||
|
RUN: llvm-ar t archive.a | FileCheck %s --check-prefix=LIST-BOTH --implicit-check-not {{.}}
|
||||||
|
RUN: llvm-ar t archive.a a\foo.txt | FileCheck %s --check-prefix=LIST-A --implicit-check-not {{.}}
|
||||||
|
RUN: llvm-ar t archive.a b\foo.txt | FileCheck %s --check-prefix=LIST-B --implicit-check-not {{.}}
|
||||||
|
|
||||||
|
LIST-BOTH: a/foo.txt
|
||||||
|
LIST-BOTH-NEXT: b/foo.txt
|
||||||
|
LIST-BOTH-NEXT: b/foo.txt
|
||||||
|
LIST-A: a/foo.txt
|
||||||
|
LIST-B: b/foo.txt
|
||||||
|
|
||||||
|
# Nesting a thin archive with a name conflict.
|
||||||
|
RUN: rm -f a\nested.a b\nested.a nested.a
|
||||||
|
RUN: llvm-ar rcST a\nested.a a\foo.txt
|
||||||
|
RUN: llvm-ar rcST b\nested.a b\foo.txt
|
||||||
|
RUN: llvm-ar rcST nested.a a\nested.a foo.txt b\nested.a
|
||||||
|
RUN: llvm-ar t nested.a | FileCheck %s --check-prefix=NESTED --implicit-check-not {{.}}
|
||||||
|
|
||||||
|
NESTED: a/foo.txt
|
||||||
|
NESTED-NEXT: foo.txt
|
||||||
|
NESTED-NEXT: b/foo.txt
|
|
@ -474,8 +474,9 @@ static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
|
||||||
outs() << Name << "\n";
|
outs() << Name << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef normalizePath(StringRef Path) {
|
static std::string normalizePath(StringRef Path) {
|
||||||
return CompareFullPath ? Path : sys::path::filename(Path);
|
return CompareFullPath ? sys::path::convert_to_slash(Path)
|
||||||
|
: sys::path::filename(Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement the 'x' operation. This function extracts files back to the file
|
// Implement the 'x' operation. This function extracts files back to the file
|
||||||
|
@ -698,9 +699,8 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
|
||||||
return IA_MoveOldMember;
|
return IA_MoveOldMember;
|
||||||
|
|
||||||
if (Operation == ReplaceOrInsert) {
|
if (Operation == ReplaceOrInsert) {
|
||||||
StringRef PosName = normalizePath(RelPos);
|
|
||||||
if (!OnlyUpdate) {
|
if (!OnlyUpdate) {
|
||||||
if (PosName.empty())
|
if (RelPos.empty())
|
||||||
return IA_AddNewMember;
|
return IA_AddNewMember;
|
||||||
return IA_MoveNewMember;
|
return IA_MoveNewMember;
|
||||||
}
|
}
|
||||||
|
@ -712,12 +712,12 @@ static InsertAction computeInsertAction(ArchiveOperation Operation,
|
||||||
auto ModTimeOrErr = Member.getLastModified();
|
auto ModTimeOrErr = Member.getLastModified();
|
||||||
failIfError(ModTimeOrErr.takeError());
|
failIfError(ModTimeOrErr.takeError());
|
||||||
if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
|
if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
|
||||||
if (PosName.empty())
|
if (RelPos.empty())
|
||||||
return IA_AddOldMember;
|
return IA_AddOldMember;
|
||||||
return IA_MoveOldMember;
|
return IA_MoveOldMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PosName.empty())
|
if (RelPos.empty())
|
||||||
return IA_AddNewMember;
|
return IA_AddNewMember;
|
||||||
return IA_MoveNewMember;
|
return IA_MoveNewMember;
|
||||||
}
|
}
|
||||||
|
@ -732,8 +732,8 @@ computeNewArchiveMembers(ArchiveOperation Operation,
|
||||||
std::vector<NewArchiveMember> Ret;
|
std::vector<NewArchiveMember> Ret;
|
||||||
std::vector<NewArchiveMember> Moved;
|
std::vector<NewArchiveMember> Moved;
|
||||||
int InsertPos = -1;
|
int InsertPos = -1;
|
||||||
StringRef PosName = normalizePath(RelPos);
|
|
||||||
if (OldArchive) {
|
if (OldArchive) {
|
||||||
|
std::string PosName = normalizePath(RelPos);
|
||||||
Error Err = Error::success();
|
Error Err = Error::success();
|
||||||
StringMap<int> MemberCount;
|
StringMap<int> MemberCount;
|
||||||
for (auto &Child : OldArchive->children(Err)) {
|
for (auto &Child : OldArchive->children(Err)) {
|
||||||
|
@ -1009,7 +1009,7 @@ static void runMRIScript() {
|
||||||
ArchiveName = Rest;
|
ArchiveName = Rest;
|
||||||
break;
|
break;
|
||||||
case MRICommand::Delete: {
|
case MRICommand::Delete: {
|
||||||
StringRef Name = normalizePath(Rest);
|
std::string Name = normalizePath(Rest);
|
||||||
llvm::erase_if(NewMembers,
|
llvm::erase_if(NewMembers,
|
||||||
[=](NewArchiveMember &M) { return M.MemberName == Name; });
|
[=](NewArchiveMember &M) { return M.MemberName == Name; });
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue