# # patch "ChangeLog" # from [45d52de4c1d3b02795d3e177dc46a7868469cbb1] # to [32b8f5570af81938c9d9ec18cc1266014cf06d17] # # patch "commands.cc" # from [619c97f154a148333f4d045bfab003359c533810] # to [afab75c11da6170ea4a46e843f53cde5c8fbc145] # # patch "pcdv.cc" # from [8f5d9105a82f69c6aea06bd547679403f979846f] # to [9e57cd05ee0304343cc53eb98a64aa0d202e4efd] # # patch "pcdv.hh" # from [e53433a7651985f8a0aeff23660f7d21f40eb813] # to [8a115dd67f2d05156cf6193834eaab0b3378f870] # --- ChangeLog +++ ChangeLog @@ -1,5 +1,10 @@ 2005-06-29 Timothy Brownawell + * pcdv.cc: more stuff in test code (same as tests in reference impl) + bugfix unique_lcs, living_status, file_state + +2005-06-29 Timothy Brownawell + * pcdv.{cc,hh}: many changes, including adding test code. Does not work properly on test code. * commands.cc: pcdv runs new test code first --- commands.cc +++ commands.cc @@ -3822,8 +3822,7 @@ "precise-cdv merge FILENAME in the two given revisions", OPT_NONE) { - if (!pcdv_test()) - return; + pcdv_test(); if (args.size() != 3) throw usage(name); @@ -3895,41 +3894,7 @@ map::iterator r = files.find(right); N(r != files.end(), F("Not found.")); vector result(l->second.conflict(r->second)); - bool lastok=false; - for (vector::iterator i = result.begin(); - i != result.end(); ++i) - { - if (i->split) - { - if (i->left.size()) - { - cout<<"<<<<<<<<<<"<<'\n'; - for (vector::iterator j = i->left.begin(); - j != i->left.end(); ++j) - cout<<" "<<*j; - } - if (i->right.size()) - { - cout<<">>>>>>>>>"<<'\n'; - for (vector::iterator j = i->right.begin(); - j != i->right.end(); ++j) - cout<<" "<<*j; - } - lastok = false; - } - else - { - if (i->left.size()) - { - if (!lastok) - cout<<"=========="<<'\n'; - for (vector::iterator j = i->left.begin(); - j != i->left.end(); ++j) - cout<<" "<<*j; - lastok = true; - } - } - } + show_conflict(consolidate(result)); } --- pcdv.cc +++ pcdv.cc @@ -23,7 +23,7 @@ file_state::~file_state() { - if (weave.unique()) + if (false && weave.unique()) { states.reset(); std::cout<<"Destroyed file_state of "<size() @@ -56,7 +56,7 @@ // btoa[i] = a.find(b[i]), if b[i] is unique in both // otherwise, btoa[i] = -1 map index2; - vector btoa(b.size()); + vector btoa(b.size(), -1); for (int i = 0; (unsigned int)(i) < b.size(); ++i) { map::iterator j = index.find(idx(b,i)); @@ -155,6 +155,7 @@ a2.push_back(idx(a, i)); for(int i = blo; i < bhi; ++i) b2.push_back(idx(b, i)); + unique_lcs(a2, b2, linematches); for (vector >::iterator i = linematches.begin(); i != linematches.end(); ++i) @@ -298,7 +299,8 @@ j != i->second.end(); ++j) alive.erase(*j); } - boost::shared_ptr > > newdict(overrides); + boost::shared_ptr > > newdict; + newdict.reset(new map >(*overrides)); map >::iterator res = newdict->insert(make_pair(rev, vector())).first; for (set::iterator i = alive.begin(); @@ -340,6 +342,16 @@ else (*newstate.states)[i->first] = i->second.merge(living_status()); } + for (map, living_status>::const_iterator i + = other.states->begin(); i != other.states->end(); ++i) + { + map, living_status>::const_iterator j + = states->find(i->first); + if (j != states->end()) + (*newstate.states)[i->first] = i->second.merge(j->second); + else + (*newstate.states)[i->first] = i->second.merge(living_status()); + } return newstate; } @@ -502,23 +514,12 @@ return out; } -bool -pcdv_test() + + +void +show_conflict(vector const & result) { - vector file; - file_state root(file, "v0"); - file.push_back("line1\n"); - file.push_back("line2\n"); - file.push_back("line3\n"); - file_state file1(root.resolve(file, "v1")); - file[1]="line2 a\n"; - file_state file2a(file1.resolve(file, "v2a")); - file[1]="line2 b\n"; - file_state file2b(file1.resolve(file, "v2b")); - - vector result=file2a.conflict(file2b); - bool lastok=false; - for (vector::iterator i = result.begin(); + for (vector::const_iterator i = result.begin(); i != result.end(); ++i) { if (i->split) @@ -526,31 +527,210 @@ if (i->left.size()) { std::cout<<"<<<<<<<<<<"<<'\n'; - for (vector::iterator j = i->left.begin(); + for (vector::const_iterator j = i->left.begin(); j != i->left.end(); ++j) std::cout<<" "<<*j; } if (i->right.size()) { - std::cout<<">>>>>>>>>"<<'\n'; - for (vector::iterator j = i->right.begin(); + std::cout<<">>>>>>>>>>"<<'\n'; + for (vector::const_iterator j = i->right.begin(); j != i->right.end(); ++j) std::cout<<" "<<*j; } - lastok = false; } else { if (i->left.size()) { - if (!lastok) - std::cout<<"=========="<<'\n'; - for (vector::iterator j = i->left.begin(); + std::cout<<"=========="<<'\n'; + for (vector::const_iterator j = i->left.begin(); j != i->left.end(); ++j) std::cout<<" "<<*j; - lastok = true; } } } - return false; } + +vector +consolidate(vector const & in) +{ + vector out; + if (!in.size()) + return out; + vector::const_iterator i = in.begin(); + out.push_back(*i); + ++i; + while (i != in.end()) + { + if (!out.back().split && !i->split) + out.back().left.insert(out.back().left.end(), + i->left.begin(), + i->left.end()); + else + out.push_back(*i); + ++i; + } + return out; +} + + + + + +vector +vectorize(string x) +{ + vector out; + for (string::iterator i = x.begin(); i != x.end(); ++i) + out.push_back(string()+(*i)+"\n"); + return out; +} + +struct vp: public vector > +{ + vp pb(int l, int r) + { + push_back(pair(l, r)); + return *this; + } +}; + +void +test_unique_lcs() +{ + // unique_lcs + vector l, r; + vector > res; + unique_lcs(l,r, res); + I(res == vp()); + + l = vectorize("a"); + r = vectorize("a"); + unique_lcs(l,r, res); + I(res == vp().pb(0, 0)); + + l = vectorize("a"); + r = vectorize("b"); + unique_lcs(l,r, res); + I(res == vp()); + + l = vectorize("ab"); + r = vectorize("ab"); + unique_lcs(l,r, res); + I(res == vp().pb(0, 0).pb(1, 1)); + + l = vectorize("abcde"); + r = vectorize("cdeab"); + unique_lcs(l,r, res); + I(res == vp().pb(2, 0).pb(3, 1).pb(4, 2)); + + l = vectorize("cdeab"); + r = vectorize("abcde"); + unique_lcs(l,r, res); + I(res == vp().pb(0, 2).pb(1, 3).pb(2, 4)); + + l = vectorize("abXde"); + r = vectorize("abYde"); + unique_lcs(l,r, res); + I(res == vp().pb(0, 0).pb(1, 1).pb(3, 3).pb(4, 4)); + + l = vectorize("acbac"); + r = vectorize("abc"); + unique_lcs(l,r, res); + I(res == vp().pb(2, 1)); +} + +void +test_recurse_matches() +{ + vector > res; + vector l, r; + + l.push_back("a\n"); + l.push_back(""); + l.push_back("b\n"); + l.push_back(""); + l.push_back("c\n"); + + r = vectorize("aabcc"); + recurse_matches(l, r, 5, 5, res, 10); + I(res == vp().pb(0, 1).pb(2, 2).pb(4, 3)); + + res.clear(); + l = vectorize("acbac"); + r = vectorize("abc"); + recurse_matches(l, r, 5, 3, res, 10); + I(res == vp().pb(0, 0).pb(2, 1).pb(4, 2)); +} + +void +test_living_status() +{ + living_status ds; + I(!ds.is_living()); + living_status ta(ds.set_living("a", true)); + I(ta.is_living()); + living_status tb(ds.set_living("b", true)); + living_status tc(ta.set_living("c", false)); + I(!tc.is_living()); + living_status td(ta.set_living("d", false)); + living_status te(tb.merge(tc)); + I(te.is_living()); + living_status tf(te.merge(td)); + I(tf.is_living()); + living_status tg(tb.set_living("g", false)); + living_status th(te.merge(tg)); + I(!th.is_living()); +} + +void +test_file_state() +{ + { + file_state ta(vectorize("abc"), "x"); + I(ta.resolve(vectorize("bcd"), "y").current() == vectorize("bcd")); + } + + { + file_state ta(vectorize("abc"), "x"); + file_state tb(ta.resolve(vectorize("dabc"), "y")); + file_state tc(ta.resolve(vectorize("abce"), "z")); + file_state td(tb.mash(tc)); + I(td.current() == vectorize("dabce")); + } + + { + file_state ta(vectorize("abc"), "x"); + file_state tb(ta.resolve(vectorize("adc"), "y")); + file_state tc(tb.resolve(vectorize("abc"), "z")); + file_state td(ta.resolve(vectorize("aec"), "w")); + + vector res(consolidate(tc.conflict(td))); + vector real; + real.push_back(vectorize("aec")); + I(res == real); + } + + { + file_state ta(vectorize("abc"), "x"); + file_state tb(ta.resolve(vectorize("adc"), "y")); + file_state tc(ta.resolve(vectorize("aec"), "z")); + + vector res(consolidate(tb.conflict(tc))); + vector real; + real.push_back(vectorize("a")); + real.push_back(merge_section(vectorize("d"), vectorize("e"))); + real.push_back(vectorize("c")); + I(res == real); + } +} + +void +pcdv_test() +{ + test_unique_lcs(); + test_recurse_matches(); + test_living_status(); + test_file_state(); +} --- pcdv.hh +++ pcdv.hh @@ -1,3 +1,6 @@ +#ifndef __PCDV_HH__ +#define __PCDV_HH__ + #include #include #include @@ -13,8 +16,6 @@ using std::make_pair; using std::set; -bool -pcdv_test(); struct merge_section { @@ -33,8 +34,20 @@ merge_section(vector const & l, vector const & r): split(true), left(l), right(r) {} + + bool + operator==(merge_section const & other) const + { + return split == other.split && left == other.left && right == other.right; + } }; +vector +consolidate(vector const & in); + +void +show_conflict(vector const & result); + // This is a const object type; there are no modifiers. struct living_status { @@ -121,3 +134,8 @@ file_state resolve(vector const & result, string revision) const; }; + +void +pcdv_test(); + +#endif