diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2008-09-05 04:26:16 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2008-09-05 04:26:16 +0000 |
commit | 76218119a2c07f8f68b43037fabcd324616ed9ee (patch) | |
tree | af1887850ebae6c5f883afbe2fb2b3bfc160a29d | |
parent | f63f39248269b44a3872af19cb47f9776dea48f3 (diff) |
Solves the issue reported in Issue 36. More merge tests now pass.
-rw-r--r-- | xdelta3/testing/regtest.cc | 33 | ||||
-rw-r--r-- | xdelta3/xdelta3-decode.h | 9 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 28 | ||||
-rw-r--r-- | xdelta3/xdelta3-merge.h | 16 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 13 |
5 files changed, 34 insertions, 65 deletions
diff --git a/xdelta3/testing/regtest.cc b/xdelta3/testing/regtest.cc index 05a27ff..c39d56c 100644 --- a/xdelta3/testing/regtest.cc +++ b/xdelta3/testing/regtest.cc | |||
@@ -690,12 +690,14 @@ void FourWayMergeTest(const TestOptions &options, | |||
690 | tcmd.push_back(recon.Name()); | 690 | tcmd.push_back(recon.Name()); |
691 | tcmd.push_back(NULL); | 691 | tcmd.push_back(NULL); |
692 | 692 | ||
693 | DP(RINT "Running one recon! %s\n", CommandToString(tcmd).c_str()); | ||
693 | CHECK_EQ(0, xd3_main_cmdline(tcmd.size() - 1, | 694 | CHECK_EQ(0, xd3_main_cmdline(tcmd.size() - 1, |
694 | const_cast<char**>(&tcmd[0]))); | 695 | const_cast<char**>(&tcmd[0]))); |
695 | DP(RINT "Ran one recon! %s\n", CommandToString(tcmd).c_str()); | ||
696 | DP(RINT "Should equal! %s\n", f2.Name()); | 696 | DP(RINT "Should equal! %s\n", f2.Name()); |
697 | 697 | ||
698 | CHECK(recon.EqualsSpec(spec2)); | 698 | CHECK(recon.EqualsSpec(spec2)); |
699 | |||
700 | /* TODO: we've only done 3-way merges, try 4-way. */ | ||
699 | } | 701 | } |
700 | 702 | ||
701 | void TestMergeCommand1() { | 703 | void TestMergeCommand1() { |
@@ -758,6 +760,8 @@ void TestMergeCommand1() { | |||
758 | 760 | ||
759 | void TestMergeCommand2() { | 761 | void TestMergeCommand2() { |
760 | /* Same as above, different mutation pattern. */ | 762 | /* Same as above, different mutation pattern. */ |
763 | /* TODO: run this with large sizes too */ | ||
764 | /* TODO: run this with small sizes too */ | ||
761 | MTRandom rand; | 765 | MTRandom rand; |
762 | FileSpec spec0(&rand); | 766 | FileSpec spec0(&rand); |
763 | FileSpec spec1(&rand); | 767 | FileSpec spec1(&rand); |
@@ -806,6 +810,7 @@ void TestMergeCommand2() { | |||
806 | spec0.ModifyTo(ChangeListMutator(cl3), &spec3); | 810 | spec0.ModifyTo(ChangeListMutator(cl3), &spec3); |
807 | 811 | ||
808 | FourWayMergeTest(options, spec0, spec1, spec2, spec3); | 812 | FourWayMergeTest(options, spec0, spec1, spec2, spec3); |
813 | FourWayMergeTest(options, spec3, spec2, spec1, spec0); | ||
809 | } | 814 | } |
810 | } | 815 | } |
811 | } | 816 | } |
@@ -816,19 +821,19 @@ void TestMergeCommand2() { | |||
816 | 821 | ||
817 | int main(int argc, char **argv) { | 822 | int main(int argc, char **argv) { |
818 | #define TEST(x) cerr << #x << "..." << endl; x() | 823 | #define TEST(x) cerr << #x << "..." << endl; x() |
819 | // TEST(TestRandomNumbers); | 824 | TEST(TestRandomNumbers); |
820 | // TEST(TestRandomFile); | 825 | TEST(TestRandomFile); |
821 | // TEST(TestFirstByte); | 826 | TEST(TestFirstByte); |
822 | // TEST(TestEmptyInMemory); | 827 | TEST(TestEmptyInMemory); |
823 | // TEST(TestBlockInMemory); | 828 | TEST(TestBlockInMemory); |
824 | // TEST(TestModifyMutator); | 829 | TEST(TestModifyMutator); |
825 | // TEST(TestAddMutator); | 830 | TEST(TestAddMutator); |
826 | // TEST(TestDeleteMutator); | 831 | TEST(TestDeleteMutator); |
827 | // TEST(TestCopyMutator); | 832 | TEST(TestCopyMutator); |
828 | // TEST(TestMoveMutator); | 833 | TEST(TestMoveMutator); |
829 | // TEST(TestOverwriteMutator); | 834 | TEST(TestOverwriteMutator); |
830 | // TEST(TestNonBlockingProgress); | 835 | TEST(TestNonBlockingProgress); |
831 | // TEST(TestMergeCommand1); | 836 | TEST(TestMergeCommand1); |
832 | TEST(TestMergeCommand2); | 837 | TEST(TestMergeCommand2); |
833 | return 0; | 838 | return 0; |
834 | } | 839 | } |
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h index d67f00a..bf2b0b1 100644 --- a/xdelta3/xdelta3-decode.h +++ b/xdelta3/xdelta3-decode.h | |||
@@ -23,15 +23,6 @@ | |||
23 | VCD_SOURCE : ((((x) & VCD_SRCORTGT) == \ | 23 | VCD_SOURCE : ((((x) & VCD_SRCORTGT) == \ |
24 | VCD_TARGET) ? VCD_TARGET : 0)) | 24 | VCD_TARGET) ? VCD_TARGET : 0)) |
25 | 25 | ||
26 | /* Return true if the caller must provide a source. Theoretically, | ||
27 | * this has to be checked after every window. It could be that the | ||
28 | * first window requires no source, but the second window does. In | ||
29 | * practice? */ | ||
30 | int xd3_decoder_needs_source (xd3_stream *stream) | ||
31 | { | ||
32 | return stream->dec_win_ind & VCD_SOURCE; | ||
33 | } | ||
34 | |||
35 | /* Initialize the decoder for a new window. The dec_tgtlen value is | 26 | /* Initialize the decoder for a new window. The dec_tgtlen value is |
36 | * preserved across successive window decodings, and the update to | 27 | * preserved across successive window decodings, and the update to |
37 | * dec_winstart is delayed until a new window actually starts. This | 28 | * dec_winstart is delayed until a new window actually starts. This |
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index c0639e0..a3f5238 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -3370,33 +3370,12 @@ main_input (xd3_cmd cmd, | |||
3370 | * the sources. */ | 3370 | * the sources. */ |
3371 | if (cmd == CMD_DECODE) | 3371 | if (cmd == CMD_DECODE) |
3372 | { | 3372 | { |
3373 | int have_src = sfile->filename != NULL; | ||
3374 | int need_src = xd3_decoder_needs_source (& stream); | ||
3375 | int recv_src; | ||
3376 | |||
3377 | /* May need to set the sfile->filename if none was given. */ | 3373 | /* May need to set the sfile->filename if none was given. */ |
3378 | main_get_appheader (& stream, ifile, ofile, sfile); | 3374 | main_get_appheader (& stream, ifile, ofile, sfile); |
3379 | 3375 | ||
3380 | recv_src = sfile->filename != NULL; | ||
3381 | |||
3382 | /* Check if the user expected a source to be required although | ||
3383 | * it was not. */ | ||
3384 | if (have_src && ! need_src && option_verbose) | ||
3385 | { | ||
3386 | XPR(NT "warning: output window %"Q"u does not " | ||
3387 | "copy source\n", stream.current_window); | ||
3388 | } | ||
3389 | |||
3390 | /* Check if we have no source name and need one. */ | ||
3391 | if (need_src && ! recv_src) | ||
3392 | { | ||
3393 | XPR(NT "input requires a source file, use -s\n"); | ||
3394 | return EXIT_FAILURE; | ||
3395 | } | ||
3396 | |||
3397 | /* Now open the source file. */ | 3376 | /* Now open the source file. */ |
3398 | if (need_src && | 3377 | if ((sfile->filename != NULL) && |
3399 | (ret = main_set_source (& stream, cmd, sfile, & source))) | 3378 | (ret = main_set_source (& stream, cmd, sfile, & source))) |
3400 | { | 3379 | { |
3401 | return EXIT_FAILURE; | 3380 | return EXIT_FAILURE; |
3402 | } | 3381 | } |
@@ -3406,8 +3385,7 @@ main_input (xd3_cmd cmd, | |||
3406 | cmd == CMD_PRINTDELTA || | 3385 | cmd == CMD_PRINTDELTA || |
3407 | cmd == CMD_RECODE) | 3386 | cmd == CMD_RECODE) |
3408 | { | 3387 | { |
3409 | if (xd3_decoder_needs_source (& stream) && | 3388 | if (sfile->filename == NULL) |
3410 | sfile->filename == NULL) | ||
3411 | { | 3389 | { |
3412 | allow_fake_source = 1; | 3390 | allow_fake_source = 1; |
3413 | sfile->filename = "<placeholder>"; | 3391 | sfile->filename = "<placeholder>"; |
diff --git a/xdelta3/xdelta3-merge.h b/xdelta3/xdelta3-merge.h index 8905643..434cf43 100644 --- a/xdelta3/xdelta3-merge.h +++ b/xdelta3/xdelta3-merge.h | |||
@@ -183,7 +183,9 @@ xd3_whole_append_inst (xd3_stream *stream, | |||
183 | } | 183 | } |
184 | else | 184 | else |
185 | { | 185 | { |
186 | winst->addr = stream->total_out + inst->addr - stream->dec_cpylen; | 186 | winst->addr = (stream->dec_winstart + |
187 | inst->addr - | ||
188 | stream->dec_cpylen); | ||
187 | } | 189 | } |
188 | break; | 190 | break; |
189 | } | 191 | } |
@@ -207,16 +209,16 @@ xd3_whole_append_window (xd3_stream *stream) | |||
207 | 209 | ||
208 | if ((stream->dec_current1.type != XD3_NOOP) && | 210 | if ((stream->dec_current1.type != XD3_NOOP) && |
209 | (ret = xd3_whole_append_inst (stream, | 211 | (ret = xd3_whole_append_inst (stream, |
210 | & stream->dec_current1))) | 212 | & stream->dec_current1))) |
211 | { | 213 | { |
212 | return ret; | 214 | return ret; |
213 | } | 215 | } |
214 | 216 | ||
215 | if ((stream->dec_current2.type != XD3_NOOP) && | 217 | if ((stream->dec_current2.type != XD3_NOOP) && |
216 | (ret = xd3_whole_append_inst (stream, | 218 | (ret = xd3_whole_append_inst (stream, |
217 | & stream->dec_current2))) | 219 | & stream->dec_current2))) |
218 | { | 220 | { |
219 | return ret; | 221 | return ret; |
220 | } | 222 | } |
221 | } | 223 | } |
222 | 224 | ||
@@ -317,8 +319,6 @@ xd3_merge_target_copy (xd3_stream *stream, | |||
317 | int ret; | 319 | int ret; |
318 | xd3_winst *oinst; | 320 | xd3_winst *oinst; |
319 | 321 | ||
320 | // TODO: this is totally untested | ||
321 | |||
322 | if ((ret = xd3_whole_alloc_winst (stream, &oinst))) | 322 | if ((ret = xd3_whole_alloc_winst (stream, &oinst))) |
323 | { | 323 | { |
324 | return ret; | 324 | return ret; |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index a989a63..fc3316a 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -1141,9 +1141,10 @@ void xd3_free_stream (xd3_stream *stream); | |||
1141 | * be called before the first xd3_encode_input. A NULL source is | 1141 | * be called before the first xd3_encode_input. A NULL source is |
1142 | * ignored. For decoding, this should be called before the first | 1142 | * ignored. For decoding, this should be called before the first |
1143 | * window is decoded, but the appheader may be read first | 1143 | * window is decoded, but the appheader may be read first |
1144 | * (XD3_GOTHEADER). At this point, consult | 1144 | * (XD3_GOTHEADER). After decoding the header, call xd3_set_source() |
1145 | * xd3_decoder_needs_source(), inlined below, to determine if a source | 1145 | * if you have a source file. Note: if (stream->dec_win_ind & VCD_SOURCE) |
1146 | * is expected by the decoder. */ | 1146 | * is true, it means the first window expects there to be a source file. |
1147 | */ | ||
1147 | int xd3_set_source (xd3_stream *stream, | 1148 | int xd3_set_source (xd3_stream *stream, |
1148 | xd3_source *source); | 1149 | xd3_source *source); |
1149 | 1150 | ||
@@ -1161,12 +1162,6 @@ int xd3_get_appheader (xd3_stream *stream, | |||
1161 | uint8_t **data, | 1162 | uint8_t **data, |
1162 | usize_t *size); | 1163 | usize_t *size); |
1163 | 1164 | ||
1164 | /* After receiving XD3_GOTHEADER, the decoder should check this | ||
1165 | * function which returns 1 if the decoder will require source | ||
1166 | * data. */ | ||
1167 | int xd3_decoder_needs_source (xd3_stream *stream); | ||
1168 | |||
1169 | |||
1170 | /* To generate a VCDIFF encoded delta with xd3_encode_init() from | 1165 | /* To generate a VCDIFF encoded delta with xd3_encode_init() from |
1171 | * another format, use: | 1166 | * another format, use: |
1172 | * | 1167 | * |