Skip to content

Commit

Permalink
Fix inserting new elements in a specified location.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
espindola committed Jul 19, 2013
1 parent 7096831 commit b55dcfe
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
13 changes: 13 additions & 0 deletions test/Object/archive-replace-pos.test
Original file line number Diff line number Diff line change
@@ -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
32 changes: 25 additions & 7 deletions tools/llvm-ar/llvm-ar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,16 @@ class NewArchiveIterator {
public:
NewArchiveIterator(object::Archive::child_iterator I, Twine Name);
NewArchiveIterator(std::vector<std::string>::const_iterator I, Twine Name);
NewArchiveIterator();
bool isNewMember() const;
object::Archive::child_iterator getOld() const;
const char *getNew() const;
StringRef getMemberName() const { return MemberName; }
};
}

NewArchiveIterator::NewArchiveIterator() {}

NewArchiveIterator::NewArchiveIterator(object::Archive::child_iterator I,
Twine Name)
: IsNewMember(false), OldI(I) {
Expand All @@ -415,14 +418,20 @@ const char *NewArchiveIterator::getNew() const {

template <typename T>
void addMember(std::vector<NewArchiveIterator> &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";
}
Expand Down Expand Up @@ -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<std::string>::iterator MI =
std::find_if(Members.begin(), Members.end(), HasName(Name));
Expand All @@ -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<std::string>::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;
Expand Down

0 comments on commit b55dcfe

Please sign in to comment.