From: Rafael Espindola Date: Fri, 19 Jul 2013 21:23:28 +0000 (+0000) Subject: Fix inserting new elements in a specified location. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b55dcfe47fbbcfc1dccd07cb27c02b9a86533d05;p=oota-llvm.git Fix inserting new elements in a specified location. We were only handling the 'a' and 'b' options during moves before. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186721 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Object/archive-replace-pos.test b/test/Object/archive-replace-pos.test new file mode 100644 index 00000000000..307f0709a79 --- /dev/null +++ b/test/Object/archive-replace-pos.test @@ -0,0 +1,13 @@ +Test adding a member to a particular position + +RUN: touch %t.foo +RUN: touch %t.bar +RUN: rm -f %t.a +RUN: llvm-ar rc %t.a %t.foo %t.bar +RUN: touch %t.zed +RUN: llvm-ar rca %t.foo %t.a %t.zed +RUN: llvm-ar t %t.a | FileCheck %s + +CHECK: .foo +CHECK-NEXT: .zed +CHECK-NEXT: .bar diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index bd10f6ffb15..4ade562ad80 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -382,6 +382,7 @@ class NewArchiveIterator { public: NewArchiveIterator(object::Archive::child_iterator I, Twine Name); NewArchiveIterator(std::vector::const_iterator I, Twine Name); + NewArchiveIterator(); bool isNewMember() const; object::Archive::child_iterator getOld() const; const char *getNew() const; @@ -389,6 +390,8 @@ public: }; } +NewArchiveIterator::NewArchiveIterator() {} + NewArchiveIterator::NewArchiveIterator(object::Archive::child_iterator I, Twine Name) : IsNewMember(false), OldI(I) { @@ -415,14 +418,20 @@ const char *NewArchiveIterator::getNew() const { template void addMember(std::vector &Members, - std::string &StringTable, T I, StringRef Name) { + std::string &StringTable, T I, StringRef Name, int Pos = -1) { if (Name.size() < 16) { NewArchiveIterator NI(I, Twine(Name) + "/"); - Members.push_back(NI); + if (Pos == -1) + Members.push_back(NI); + else + Members[Pos] = NI; } else { int MapIndex = StringTable.size(); NewArchiveIterator NI(I, Twine("/") + Twine(MapIndex)); - Members.push_back(NI); + if (Pos == -1) + Members.push_back(NI); + else + Members[Pos] = NI; StringTable += Name; StringTable += "/\n"; } @@ -462,6 +471,8 @@ computeNewArchiveMembers(ArchiveOperation Operation, else InsertPos = Pos + 1; } + if (InsertPos == Pos) + Ret.resize(Ret.size() + Members.size()); if (Operation != QuickAppend && !Members.empty()) { std::vector::iterator MI = std::find_if(Members.begin(), Members.end(), HasName(Name)); @@ -488,23 +499,30 @@ computeNewArchiveMembers(ArchiveOperation Operation, if (Operation == Delete) return Ret; + if (!RelPos.empty() && InsertPos == -1) + fail("Insertion point not found"); + if (Operation == Move) { + if (Members.size() != Moved.size()) + fail("A member to be moved is not present in the archive"); + if (RelPos.empty()) { Ret.insert(Ret.end(), Moved.begin(), Moved.end()); return Ret; } - if (InsertPos == -1) - fail("Insertion point not found"); assert(unsigned(InsertPos) <= Ret.size()); - Ret.insert(Ret.begin() + InsertPos, Moved.begin(), Moved.end()); + std::copy(Moved.begin(), Moved.end(), Ret.begin() + InsertPos); return Ret; } + int Pos = InsertPos; for (std::vector::iterator I = Members.begin(), E = Members.end(); I != E; ++I) { StringRef Name = sys::path::filename(*I); - addMember(Ret, StringTable, I, Name); + addMember(Ret, StringTable, I, Name, Pos); + if (Pos != -1) + ++Pos; } return Ret;