Add the following packages libalgorithm-diff-perl libspiffy-perl libtext-diff-perl...
authorNito Martinez <Nito@Qindel.ES>
Wed, 14 Apr 2010 06:38:38 +0000 (07:38 +0100)
committerNito Martinez <Nito@Qindel.ES>
Wed, 14 Apr 2010 06:38:38 +0000 (07:38 +0100)
313 files changed:
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/Changes [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/MANIFEST [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/META.yml [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/Makefile.PL [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/README [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/cdiff.pl [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/changelog [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/compat [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/control [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/copyright [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/rules [new file with mode: 0755]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/watch [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/diff.pl [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/diffnew.pl [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/htmldiff.pl [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/lib/Algorithm/Diff.pm [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/lib/Algorithm/DiffOld.pm [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/t/base.t [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/t/oo.t [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.diff.gz [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.dsc [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.diff.gz [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.dsc [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1_armel.changes [new file with mode: 0644]
deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02.orig.tar.gz [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Call/Call.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Call/Call.xs [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Call/Makefile.PL [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/Call/ppport.h [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Changes [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Exec.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Exec.xs [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Makefile.PL [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/MANIFEST [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/META.yml [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/Makefile.PL [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/README [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/changelog [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/compat [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/control [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/copyright [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/docs [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/examples [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/rules [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/debian/watch [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/Makefile.PL [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decr [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decrypt.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decrypt.xs [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/encrypt [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Count.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Decompress.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Include.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Joe2Jim.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/NewSubst.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Subst.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/UUdecode.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/filtdef [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/filtuu [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Count.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Decompress.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Joe2Jim.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/NewSubst.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Subst.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/UUdecode.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/filter-util.pl [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/lib/Filter/cpp.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/lib/Filter/exec.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/lib/Filter/sh.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/mytest [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/perlfilter.pod [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/call.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/cpp.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/decrypt.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/exec.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/order.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/pod.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/sh.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/t/tee.t [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/tee/Makefile.PL [new file with mode: 0755]
deb-src/libfilter-perl/libfilter-perl-1.34/tee/tee.pm [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl-1.34/tee/tee.xs [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl_1.34-1.diff.gz [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl_1.34-1.dsc [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl_1.34-1maemo1.diff.gz [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl_1.34-1maemo1.dsc [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl_1.34-1maemo1_armel.changes [new file with mode: 0644]
deb-src/libfilter-perl/libfilter-perl_1.34.orig.tar.gz [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/Changes [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/MANIFEST [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/META.yml [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/Makefile.PL [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/README [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/debian/changelog [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/debian/compat [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/debian/control [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/debian/copyright [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/debian/rules [new file with mode: 0755]
deb-src/libspiffy-perl/libspiffy-perl-0.30/debian/watch [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/Base.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/Can.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/Fetch.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/Makefile.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/Metadata.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/Win32.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/inc/Module/Install/WriteAll.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/lib/Spiffy.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/Filter4.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/Filter5.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/NonSpiffy.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/Something.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/Thing.pm [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/autoload.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/base.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/base2.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/cascade.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/const.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/early.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export1.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export2.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export3.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export4.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export5.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export6.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/export7.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/exporter.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/field.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/field2.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/field3.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/filter.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/filter2.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/filter3.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/filter4.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/filter5.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/mixin.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/mixin2.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/mixin3.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/new.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/package.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/parse.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/stub.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/super.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl-0.30/t/super2.t [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl_0.30-1.diff.gz [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl_0.30-1.dsc [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl_0.30-1maemo1.diff.gz [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl_0.30-1maemo1.dsc [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl_0.30-1maemo1_armel.changes [new file with mode: 0644]
deb-src/libspiffy-perl/libspiffy-perl_0.30.orig.tar.gz [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/Changes [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/MANIFEST [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/META.yml [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/Makefile.PL [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/README [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/debian/changelog [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/debian/compat [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/debian/control [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/debian/copyright [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/debian/rules [new file with mode: 0755]
deb-src/libtest-base-perl/libtest-base-perl-0.54/debian/watch [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/Base.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/Can.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/Fetch.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/Makefile.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/Metadata.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/Win32.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/inc/Module/Install/WriteAll.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/lib/Module/Install/TestBase.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/lib/Test/Base.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/lib/Test/Base/Filter.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/BaseTest.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/Subclass.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/Test-Less/index.txt [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/TestA.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/TestB.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/TestBass.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/TestC.pm [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/append.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/arguments.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/array.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/autoload.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/base64.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/blocks-scalar.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/blocks_grep.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/chomp.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/chop.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/compact.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/compile.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/delimiters.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/description.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/diff_is.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/dos_spec [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/dumper.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/embed_perl.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/escape.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/eval.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/eval_all.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/eval_stderr.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/eval_stdout.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/export.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/filter_arguments.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/filter_delay.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/filter_functions.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/filters-append.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/filters.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/filters_map.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/first_block.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/flatten.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/get_url.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/hash.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/head.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/internals.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/is.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/jit-run.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/join-deep.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/join.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/last.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/late.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/lazy-filters.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/lines.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/list.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/main_filters.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/multi-level-inherit.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/name.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/next.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/no_diff.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/no_plan.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/normalize.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/only-with-implicit.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/only.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/oo.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/oo_run.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/parentheses.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/prepend.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/preserve-order.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/prototypes.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/quick-plan.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/quick_test.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/read_file.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/regexp.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/repeated-filters.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/require.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/reserved_names.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/reverse-deep.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/reverse.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/run-args.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/run_compare.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/run_is.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/run_is_deeply.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/run_like.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/run_unlike.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/sample-file.txt [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/simple.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/skip.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/slice.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/sort-deep.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/sort.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/spec1 [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/spec2 [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/spec_file.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/spec_string.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/split-deep.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/split-regexp.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/split.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/strict-warnings.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/strict-warnings.test [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/strict.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/subclass-autoclass.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/subclass-import.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/subclass.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/subclass_late.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/tail.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/tie_output.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/trim.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/unchomp.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/use-test-more.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/write_file.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/xxx.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/yaml.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl-0.54/t/zero-blocks.t [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl_0.54-1.diff.gz [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl_0.54-1.dsc [new file with mode: 0644]
deb-src/libtest-base-perl/libtest-base-perl_0.54.orig.tar.gz [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/Changes [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/MANIFEST [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/MANIFEST.SKIP [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/Makefile.PL [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/debian/changelog [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/debian/compat [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/debian/control [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/debian/copyright [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/debian/rules [new file with mode: 0755]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/debian/watch [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/lib/Text/Diff.pm [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/lib/Text/Diff/Table.pm [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/t/ext_format.t [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/t/general.t [new file with mode: 0755]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/t/inputs.t [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/t/keygen.t [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/t/outputs.t [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl-0.35/t/table.t [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl_0.35-3.diff.gz [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl_0.35-3.dsc [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl_0.35-3maemo1.diff.gz [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl_0.35-3maemo1.dsc [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl_0.35-3maemo1_armel.changes [new file with mode: 0644]
deb-src/libtext-diff-perl/libtext-diff-perl_0.35.orig.tar.gz [new file with mode: 0644]
deb/pool/main/liba/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1_all.deb [new file with mode: 0644]
deb/pool/main/libf/libfilter-perl/libfilter-perl_1.34-1maemo1_armel.deb [new file with mode: 0644]
deb/pool/main/libs/libspiffy-perl/libspiffy-perl_0.30-1maemo1_all.deb [new file with mode: 0644]
deb/pool/main/libt/libtext-diff-perl/libtext-diff-perl_0.35-3maemo1_all.deb [new file with mode: 0644]

diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/Changes b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/Changes
new file mode 100644 (file)
index 0000000..19c58b4
--- /dev/null
@@ -0,0 +1,47 @@
+Revision history for Perl module Algorithm::Diff.
+
+1.19_02 2006-07-31
+- Fix typo in @EXPORT_OK (s/LCDidx/LCSidx/) (RT 8576)
+- Use 'printf' in example code, not 'sprintf' nor 'sprint' (RT 16067)
+- DiffOld wasn't passing extra arguments to compare routine (RT 20650)
+
+1.19 2004-09-22
+- Added OO interface.
+- Based on Ned's v1.18 (unreleased)
+
+1.13 Sun Mar 24 16:05:32 PST 2002
+- sdiff and traverse_balanced added by Mike Schilli <m@perlmeister.com>.
+
+1.11 Thu Jul 12 12:52:18 PDT 2001
+- Added A_FINISHED and B_FINISHED per docs
+- Called user callback function from keygen properly
+
+1.10 July 7 2000
+- Uploaded to CPAN
+- More optimizations
+- Added Algorithm::DiffOld
+
+1.08
+- Fixed bug with binary search that was making diff output too big
+
+1.06 Wed Jun 14 14:15:31 PDT 2000
+- First CPAN version by NEDKONZ
+- Added MJD's list info to README
+
+1.05 Sun Jun 11 15:17:05 PDT 2000
+- Changed version label string.
+- Put MJD's PPT diff version into this distribution as diffnew.pl
+
+1.04 Added documentation. 
+
+1.03 Working version
+
+1.01 First version by Ned Konz.
+- Total re-write to cure problems with memory usage and speed.
+  Now takes only a few seconds and less than three megabytes
+  to compare two 4000-line files.
+
+- Changed optional callback function reference from being equality
+  function to being key (hash) generation function.
+
+0.59 Last version maintained by Mark-Jason Dominus
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/MANIFEST b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/MANIFEST
new file mode 100644 (file)
index 0000000..8e139c8
--- /dev/null
@@ -0,0 +1,13 @@
+Changes
+lib/Algorithm/Diff.pm       Algorithm::Diff perl module
+lib/Algorithm/DiffOld.pm    Algorithm::Diff perl module with old behavior
+Makefile.PL
+MANIFEST
+README
+t/base.t                    Basic test script
+t/oo.t                      OO interface test script
+cdiff.pl                    Context diff utility
+diff.pl                     Simple Unix diff utility written in Perl
+diffnew.pl                  Full-featured Unix diff utility written in Perl
+htmldiff.pl                 Sample using traverse_sequences
+META.yml                    Module meta-data (added by MakeMaker)
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/META.yml b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/META.yml
new file mode 100644 (file)
index 0000000..57c174f
--- /dev/null
@@ -0,0 +1,10 @@
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
+name:         Algorithm-Diff
+version:      1.1902
+version_from: lib/Algorithm/Diff.pm
+installdirs:  site
+requires:
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.17
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/Makefile.PL b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/Makefile.PL
new file mode 100644 (file)
index 0000000..253f1df
--- /dev/null
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'          => 'Algorithm::Diff',
+    'VERSION_FROM'  => 'lib/Algorithm/Diff.pm', # finds $VERSION
+);
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/README b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/README
new file mode 100644 (file)
index 0000000..f12a0f4
--- /dev/null
@@ -0,0 +1,81 @@
+This is a module for computing the difference between two files, two
+strings, or any other two lists of things.  It uses an intelligent
+algorithm similar to (or identical to) the one used by the Unix "diff"
+program.  It is guaranteed to find the *smallest possible* set of
+differences.
+
+This package contains a few parts.
+
+Algorithm::Diff is the module that contains several interfaces for which
+computing the differences betwen two lists.
+
+The several "diff" programs also included in this package use
+Algorithm::Diff to find the differences and then they format the output.
+
+Algorithm::Diff also includes some other useful functions such as "LCS",
+which computes the longest common subsequence of two lists.
+
+A::D is suitable for many uses.  You can use it for finding the smallest
+set of differences between two strings, or for computing the most
+efficient way to update the screen if you were replacing "curses".
+
+Algorithm::DiffOld is a previous version of the module which is included
+primarilly for those wanting to use a custom comparison function rather
+than a key generating function (and who don't mind the significant
+performance penalty of perhaps 20-fold).
+
+diff.pl implements a "diff" in Perl that is as simple as (was
+previously) possible so that you can see how it works.  The output
+format is not compatible with regular "diff".  It needs to be
+reimplemented using the OO interface to greatly simplify the code.
+
+diffnew.pl implements a "diff" in Perl with full bells and whistles.  By
+Mark-Jason, with code from cdiff.pl included.
+
+cdiff.pl implements "diff" that generates real context diffs in either
+traditional format or GNU unified format.  Original contextless
+"context" diff supplied by Christian Murphy.  Modifications to make it
+into a real full-featured diff with -c and -u options supplied by Amir
+D. Karger.
+
+Yes, you can use this program to generate patches.
+
+OTHER RESOURCES
+
+"Longest Common Subsequences", at
+http://www.ics.uci.edu/~eppstein/161/960229.html
+
+This code was adapted from the Smalltalk code of Mario Wolczko
+<mario@wolczko.com>, which is available at
+ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
+
+THANKS SECTION
+
+Thanks to Ned Konz's for rewriting the module to greatly improve
+performance, for maintaining it over the years, and for readilly handing
+it over to me so I could plod along with my improvements.
+
+(From Ned Konz's earlier versions):
+
+Thanks to Mark-Jason Dominus for doing the original Perl version and
+maintaining it over the last couple of years. Mark-Jason has been a huge
+contributor to the Perl community and CPAN; it's because of people like
+him that Perl has become a success.
+
+Thanks to Mario Wolczko <mario@wolczko.com> for writing and making
+publicly available his Smalltalk version of diff, which this Perl
+version is heavily based on.
+
+Thanks to Mike Schilli <m@perlmeister.com> for writing sdiff and
+traverse_balanced and making them available for the Algorithm::Diff
+distribution.
+
+(From Mark-Jason Dominus' earlier versions):
+
+Huge thanks to Amir Karger for adding full context diff supprt to
+"cdiff.pl", and then for waiting patiently for five months while I let
+it sit in a closet and didn't release it.  Thank you thank you thank
+you, Amir!
+
+Thanks to Christian Murphy for adding the first context diff format
+support to "cdiff.pl".
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/cdiff.pl b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/cdiff.pl
new file mode 100644 (file)
index 0000000..7c9140b
--- /dev/null
@@ -0,0 +1,385 @@
+#!/usr/bin/perl -w
+#
+# `Diff' program in Perl
+# Copyright 1998 M-J. Dominus. (mjd-perl-diff@plover.com)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+#
+# Altered to output in `context diff' format (but without context)
+# September 1998 Christian Murphy (cpm@muc.de)
+#
+# Command-line arguments and context lines feature added
+# September 1998 Amir D. Karger (karger@bead.aecom.yu.edu)
+#
+# In this file, "item" usually means "line of text", and "item number" usually
+# means "line number". But theoretically the code could be used more generally
+use strict;
+
+use Algorithm::Diff qw(diff);
+use File::stat;
+use vars qw ($opt_C $opt_c $opt_u $opt_U);
+use Getopt::Std;
+
+my $usage = << "ENDUSAGE";
+Usage: $0 [{-c | -u}] [{-C | -U} lines] oldfile newfile
+    -c will do a context diff with 3 lines of context
+    -C will do a context diff with 'lines' lines of context
+    -u will do a unified diff with 3 lines of context
+    -U will do a unified diff with 'lines' lines of context
+ENDUSAGE
+
+getopts('U:C:cu') or bag("$usage");
+bag("$usage") unless @ARGV == 2;
+my ($file1, $file2) = @ARGV;
+if (defined $opt_C || defined $opt_c) {
+    $opt_c = ""; # -c on if -C given on command line
+    $opt_u = undef;
+} elsif (defined $opt_U || defined $opt_u) {
+    $opt_u = ""; # -u on if -U given on command line
+    $opt_c = undef;
+} else {
+    $opt_c = ""; # by default, do context diff, not old diff
+}
+
+my ($char1, $char2); # string to print before file names
+my $Context_Lines; # lines of context to print
+if (defined $opt_c) {
+    $Context_Lines = defined $opt_C ? $opt_C : 3;
+    $char1 = '*' x 3; $char2 = '-' x 3;
+} elsif (defined $opt_u) {
+    $Context_Lines = defined $opt_U ? $opt_U : 3;
+    $char1 = '-' x 3; $char2 = '+' x 3;
+}
+
+# After we've read up to a certain point in each file, the number of items
+# we've read from each file will differ by $FLD (could be 0)
+my $File_Length_Difference = 0;
+
+open (F1, $file1) or bag("Couldn't open $file1: $!");
+open (F2, $file2) or bag("Couldn't open $file2: $!");
+my (@f1, @f2);
+chomp(@f1 = <F1>);
+close F1;
+chomp(@f2 = <F2>);
+close F2;
+
+# diff yields lots of pieces, each of which is basically a Block object
+my $diffs = diff(\@f1, \@f2);
+exit 0 unless @$diffs;
+
+my $st = stat($file1);
+print "$char1 $file1\t", scalar localtime($st->mtime), "\n";
+$st = stat($file2);
+print "$char2 $file2\t", scalar localtime($st->mtime), "\n";
+
+my ($hunk,$oldhunk);
+# Loop over hunks. If a hunk overlaps with the last hunk, join them.
+# Otherwise, print out the old one.
+foreach my $piece (@$diffs) {
+    $hunk = new Hunk ($piece, $Context_Lines);
+    next unless $oldhunk;
+
+    if ($hunk->does_overlap($oldhunk)) {
+       $hunk->prepend_hunk($oldhunk);
+    } else {
+       $oldhunk->output_diff(\@f1, \@f2);
+    }
+
+} continue {
+    $oldhunk = $hunk;
+}
+
+# print the last hunk
+$oldhunk->output_diff(\@f1, \@f2);
+exit 1;
+# END MAIN PROGRAM
+
+sub bag {
+  my $msg = shift;
+  $msg .= "\n";
+  warn $msg;
+  exit 2;
+}
+
+# Package Hunk. A Hunk is a group of Blocks which overlap because of the
+# context surrounding each block. (So if we're not using context, every
+# hunk will contain one block.)
+{
+package Hunk;
+
+sub new {
+# Arg1 is output from &LCS::diff (which corresponds to one Block)
+# Arg2 is the number of items (lines, e.g.,) of context around each block
+#
+# This subroutine changes $File_Length_Difference
+#
+# Fields in a Hunk:
+# blocks      - a list of Block objects
+# start       - index in file 1 where first block of the hunk starts
+# end         - index in file 1 where last block of the hunk ends
+#
+# Variables:
+# before_diff - how much longer file 2 is than file 1 due to all hunks
+#               until but NOT including this one
+# after_diff  - difference due to all hunks including this one
+    my ($class, $piece, $context_items) = @_;
+
+    my $block = new Block ($piece); # this modifies $FLD!
+
+    my $before_diff = $File_Length_Difference; # BEFORE this hunk
+    my $after_diff = $before_diff + $block->{"length_diff"};
+    $File_Length_Difference += $block->{"length_diff"};
+
+    # @remove_array and @insert_array hold the items to insert and remove
+    # Save the start & beginning of each array. If the array doesn't exist
+    # though (e.g., we're only adding items in this block), then figure
+    # out the line number based on the line number of the other file and
+    # the current difference in file lenghts
+    my @remove_array = $block->remove;
+    my @insert_array = $block->insert;
+    my ($a1, $a2, $b1, $b2, $start1, $start2, $end1, $end2);
+    $a1 = @remove_array ? $remove_array[0 ]->{"item_no"} : -1;
+    $a2 = @remove_array ? $remove_array[-1]->{"item_no"} : -1;
+    $b1 = @insert_array ? $insert_array[0 ]->{"item_no"} : -1;
+    $b2 = @insert_array ? $insert_array[-1]->{"item_no"} : -1;
+
+    $start1 = $a1 == -1 ? $b1 - $before_diff : $a1;
+    $end1   = $a2 == -1 ? $b2 - $after_diff  : $a2;
+    $start2 = $b1 == -1 ? $a1 + $before_diff : $b1;
+    $end2   = $b2 == -1 ? $a2 + $after_diff  : $b2;
+
+    # At first, a hunk will have just one Block in it
+    my $hunk = {
+           "start1" => $start1,
+           "start2" => $start2,
+           "end1" => $end1,
+           "end2" => $end2,
+           "blocks" => [$block],
+              };
+    bless $hunk, $class;
+
+    $hunk->flag_context($context_items);
+
+    return $hunk;
+}
+
+# Change the "start" and "end" fields to note that context should be added
+# to this hunk
+sub flag_context {
+    my ($hunk, $context_items) = @_;
+    return unless $context_items; # no context
+
+    # add context before
+    my $start1 = $hunk->{"start1"};
+    my $num_added = $context_items > $start1 ? $start1 : $context_items;
+    $hunk->{"start1"} -= $num_added;
+    $hunk->{"start2"} -= $num_added;
+
+    # context after
+    my $end1 = $hunk->{"end1"};
+    $num_added = ($end1+$context_items > $#f1) ?
+                  $#f1 - $end1 :
+                  $context_items;
+    $hunk->{"end1"} += $num_added;
+    $hunk->{"end2"} += $num_added;
+}
+
+# Is there an overlap between hunk arg0 and old hunk arg1?
+# Note: if end of old hunk is one less than beginning of second, they overlap
+sub does_overlap {
+    my ($hunk, $oldhunk) = @_;
+    return "" unless $oldhunk; # first time through, $oldhunk is empty
+
+    # Do I actually need to test both?
+    return ($hunk->{"start1"} - $oldhunk->{"end1"} <= 1 ||
+            $hunk->{"start2"} - $oldhunk->{"end2"} <= 1);
+}
+
+# Prepend hunk arg1 to hunk arg0
+# Note that arg1 isn't updated! Only arg0 is.
+sub prepend_hunk {
+    my ($hunk, $oldhunk) = @_;
+
+    $hunk->{"start1"} = $oldhunk->{"start1"};
+    $hunk->{"start2"} = $oldhunk->{"start2"};
+
+    unshift (@{$hunk->{"blocks"}}, @{$oldhunk->{"blocks"}});
+}
+
+
+# DIFF OUTPUT ROUTINES. THESE ROUTINES CONTAIN DIFF FORMATTING INFO...
+sub output_diff {
+    if    (defined $main::opt_u) {&output_unified_diff(@_)}
+    elsif (defined $main::opt_c) {&output_context_diff(@_)}
+    else {die "unknown diff"}
+}
+
+sub output_unified_diff {
+    my ($hunk, $fileref1, $fileref2) = @_;
+    my @blocklist;
+
+    # Calculate item number range.
+    my $range1 = $hunk->unified_range(1);
+    my $range2 = $hunk->unified_range(2);
+    print "@@ -$range1 +$range2 @@\n";
+
+    # Outlist starts containing the hunk of file 1.
+    # Removing an item just means putting a '-' in front of it.
+    # Inserting an item requires getting it from file2 and splicing it in.
+    #    We splice in $num_added items. Remove blocks use $num_added because
+    # splicing changed the length of outlist.
+    #    We remove $num_removed items. Insert blocks use $num_removed because
+    # their item numbers---corresponding to positions in file *2*--- don't take
+    # removed items into account.
+    my $low = $hunk->{"start1"};
+    my $hi = $hunk->{"end1"};
+    my ($num_added, $num_removed) = (0,0);
+    my @outlist = @$fileref1[$low..$hi];
+    map {s/^/ /} @outlist; # assume it's just context
+
+    foreach my $block (@{$hunk->{"blocks"}}) {
+       foreach my $item ($block->remove) {
+           my $op = $item->{"sign"}; # -
+           my $offset = $item->{"item_no"} - $low + $num_added;
+           $outlist[$offset] =~ s/^ /$op/;
+           $num_removed++;
+       }
+       foreach my $item ($block->insert) {
+           my $op = $item->{"sign"}; # +
+           my $i = $item->{"item_no"};
+           my $offset = $i - $hunk->{"start2"} + $num_removed;
+           splice(@outlist,$offset,0,"$op$$fileref2[$i]");
+           $num_added++;
+       }
+    }
+
+    map {s/$/\n/} @outlist; # add \n's
+    print @outlist;
+
+}
+
+sub output_context_diff {
+    my ($hunk, $fileref1, $fileref2) = @_;
+    my @blocklist;
+
+    print "***************\n";
+    # Calculate item number range.
+    my $range1 = $hunk->context_range(1);
+    my $range2 = $hunk->context_range(2);
+
+    # Print out file 1 part for each block in context diff format if there are
+    # any blocks that remove items
+    print "*** $range1 ****\n";
+    my $low = $hunk->{"start1"};
+    my $hi  = $hunk->{"end1"};
+    if (@blocklist = grep {$_->remove} @{$hunk->{"blocks"}}) {
+       my @outlist = @$fileref1[$low..$hi];
+       map {s/^/  /} @outlist; # assume it's just context
+       foreach my $block (@blocklist) {
+           my $op = $block->op; # - or !
+           foreach my $item ($block->remove) {
+               $outlist[$item->{"item_no"} - $low] =~ s/^ /$op/;
+           }
+       }
+       map {s/$/\n/} @outlist; # add \n's
+       print @outlist;
+    }
+
+    print "--- $range2 ----\n";
+    $low = $hunk->{"start2"};
+    $hi  = $hunk->{"end2"};
+    if (@blocklist = grep {$_->insert} @{$hunk->{"blocks"}}) {
+       my @outlist = @$fileref2[$low..$hi];
+       map {s/^/  /} @outlist; # assume it's just context
+       foreach my $block (@blocklist) {
+           my $op = $block->op; # + or !
+           foreach my $item ($block->insert) {
+               $outlist[$item->{"item_no"} - $low] =~ s/^ /$op/;
+           }
+       }
+       map {s/$/\n/} @outlist; # add \n's
+       print @outlist;
+    }
+}
+
+sub context_range {
+# Generate a range of item numbers to print. Only print 1 number if the range
+# has only one item in it. Otherwise, it's 'start,end'
+    my ($hunk, $flag) = @_;
+    my ($start, $end) = ($hunk->{"start$flag"},$hunk->{"end$flag"});
+    $start++; $end++;  # index from 1, not zero
+    my $range = ($start < $end) ? "$start,$end" : $end;
+    return $range;
+}
+
+sub unified_range {
+# Generate a range of item numbers to print for unified diff
+# Print number where block starts, followed by number of lines in the block
+# (don't print number of lines if it's 1)
+    my ($hunk, $flag) = @_;
+    my ($start, $end) = ($hunk->{"start$flag"},$hunk->{"end$flag"});
+    $start++; $end++;  # index from 1, not zero
+    my $length = $end - $start + 1;
+    my $first = $length < 2 ? $end : $start; # strange, but correct...
+    my $range = $length== 1 ? $first : "$first,$length";
+    return $range;
+}
+} # end Package Hunk
+
+# Package Block. A block is an operation removing, adding, or changing
+# a group of items. Basically, this is just a list of changes, where each
+# change adds or deletes a single item.
+# (Change could be a separate class, but it didn't seem worth it)
+{
+package Block;
+sub new {
+# Input is a chunk from &Algorithm::LCS::diff
+# Fields in a block:
+# length_diff - how much longer file 2 is than file 1 due to this block
+# Each change has:
+# sign        - '+' for insert, '-' for remove
+# item_no     - number of the item in the file (e.g., line number)
+# We don't bother storing the text of the item
+#
+    my ($class,$chunk) = @_;
+    my @changes = ();
+
+# This just turns each change into a hash.
+    foreach my $item (@$chunk) {
+       my ($sign, $item_no, $text) = @$item;
+       my $hashref = {"sign" => $sign, "item_no" => $item_no};
+       push @changes, $hashref;
+    }
+
+    my $block = { "changes" => \@changes };
+    bless $block, $class;
+
+    $block->{"length_diff"} = $block->insert - $block->remove;
+    return $block;
+}
+
+
+# LOW LEVEL FUNCTIONS
+sub op {
+# what kind of block is this?
+    my $block = shift;
+    my $insert = $block->insert;
+    my $remove = $block->remove;
+
+    $remove && $insert and return '!';
+    $remove and return '-';
+    $insert and return '+';
+    warn "unknown block type";
+    return '^'; # context block
+}
+
+# Returns a list of the changes in this block that remove items
+# (or the number of removals if called in scalar context)
+sub remove { return grep {$_->{"sign"} eq '-'} @{shift->{"changes"}}; }
+
+# Returns a list of the changes in this block that insert items
+sub insert { return grep {$_->{"sign"} eq '+'} @{shift->{"changes"}}; }
+
+} # end of package Block
+
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/changelog b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/changelog
new file mode 100644 (file)
index 0000000..ce7d4aa
--- /dev/null
@@ -0,0 +1,113 @@
+libalgorithm-diff-perl (1.19.02-1maemo1) fremantle; urgency=low
+
+  * New Maemo packaging
+
+ -- Nito Martinez <Nito@Qindel.ES>  Wed, 14 Apr 2010 07:09:51 +0100
+
+
+llibalgorithm-diff-perl (1.19.02-1) unstable; urgency=low
+
+  * Take over for the Debian Perl Group on maintainer's request
+    (http://lists.debian.org/debian-perl/2008/03/msg00055.html)
+  * debian/control: Added: Vcs-Svn field (source stanza); Vcs-Browser
+    field (source stanza); Homepage field (source stanza). Changed:
+    Maintainer set to Debian Perl Group <pkg-perl-
+    maintainers@lists.alioth.debian.org> (was: Florian Weimer
+    <fw@deneb.enyo.de>).
+  * debian/watch: add uversionmangle.
+
+  * New upstream release (includes both patches from earlier Debian
+    versions: "export LCSidx" and "typo in example").
+  * Set Standards-Version to 3.7.3 (no changes).
+  * Set debhelper compatibility level to 5 (and add debian/compat).
+  * debian/control:
+    - add /me to Uploaders
+    - remove Section and Priority from binary package stanza
+    - move debhelper to Build-Depends
+  * Remove debian/libalgorithm-diff-perl.dirs.
+  * debian/rules: update based on dh-make-perl's templates.
+  * debian/copyright: mention Debian Perl Group, add additional copyright
+    holder, use specific download URL instead of pointing to CPAN at large.
+
+ -- gregor herrmann <gregor+debian@comodo.priv.at>  Sun, 09 Mar 2008 23:20:32 +0100
+
+libalgorithm-diff-perl (1.19.01-2) unstable; urgency=low
+
+  * Update debian/watch to match only relevant .tar.gz files.
+  * Apply patch from Martin Zobel-Helas to properly export LCSidx.
+    Closes: #341227.
+  * Fix typo in Diff.pm example (upstream bug 16067).
+  * Bump Standards-Version to 3.6.2.1.  No changes necessary.
+
+ -- Florian Weimer <fw@deneb.enyo.de>  Tue, 29 Nov 2005 15:05:46 +0100
+
+libalgorithm-diff-perl (1.19.01-1) unstable; urgency=low
+
+  * New upstream release.
+  * Adopt the package.  Closes: #274119.
+
+ -- Florian Weimer <fw@deneb.enyo.de>  Fri,  1 Oct 2004 10:52:39 +0200
+
+libalgorithm-diff-perl (1.15-5) unstable; urgency=low
+
+  * Rebuild so that .arch-ids/ files don't get included in the package.
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Tue, 23 Dec 2003 19:37:44 -0500
+
+libalgorithm-diff-perl (1.15-4) unstable; urgency=low
+
+  * Update standards version
+  * Remove examples file, since examples are being dealt with in a
+    different manner
+
+ -- Michael Alan Dorman <mdorman@mallet-assembly.org>  Fri, 19 Dec 2003 14:43:54 -0500
+
+libalgorithm-diff-perl (1.15-3) unstable; urgency=low
+
+  * Fix override disparity.
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Fri, 15 Aug 2003 18:40:06 -0400
+
+libalgorithm-diff-perl (1.15-2) unstable; urgency=low
+
+  * Fix some problems with the copyright statement. (closes: Bug#157538)
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Sat, 15 Mar 2003 14:12:36 -0500
+
+libalgorithm-diff-perl (1.15-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Sun,  7 Jul 2002 16:04:53 -0400
+
+libalgorithm-diff-perl (1.11a-1) unstable; urgency=low
+
+  * New upstream version (closes: bug#128190)
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Tue, 22 Jan 2002 13:12:31 -0500
+
+libalgorithm-diff-perl (1.10-3) unstable; urgency=low
+
+  * Whooops!  My package somehow got screwed up, with the newer version of
+    the module appended to the text of the older module.  Fixed.
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Sun, 15 Apr 2001 21:11:44 -0400
+
+libalgorithm-diff-perl (1.10-2) unstable; urgency=low
+
+  * Add build-depends.
+  * Many edits to rules file.
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Sun, 15 Apr 2001 14:39:34 -0400
+
+libalgorithm-diff-perl (1.10-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Wed, 20 Sep 2000 15:31:15 -0400
+
+libalgorithm-diff-perl (0.59-1) unstable; urgency=low
+
+  * Initial packaging
+
+ -- Michael Alan Dorman <mdorman@debian.org>  Sat,  8 Apr 2000 17:55:34 -0400
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/compat b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/control b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/control
new file mode 100644 (file)
index 0000000..76f5f67
--- /dev/null
@@ -0,0 +1,19 @@
+Source: libalgorithm-diff-perl
+Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>
+Uploaders: gregor herrmann <gregor+debian@comodo.priv.at>
+Priority: optional
+Section: perl
+Build-Depends: debhelper (>= 5)
+Build-Depends-Indep: perl (>= 5.6.0-16)
+Standards-Version: 3.7.3
+Homepage: http://search.cpan.org/dist/Algorithm-Diff/
+Vcs-Svn: svn://svn.debian.org/pkg-perl/trunk/libalgorithm-diff-perl/
+Vcs-Browser: http://svn.debian.org/wsvn/pkg-perl/trunk/libalgorithm-diff-perl/
+
+Package: libalgorithm-diff-perl
+Architecture: all
+Depends: ${perl:Depends}
+Description: a perl library for finding Longest Common Sequences in text
+ This module provides routines that allow one to analyze text in perl
+ arrays to produce a Longest Common Sequence, which can in turn be
+ used to produce the same information as the common Unix tool 'diff'
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/copyright b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/copyright
new file mode 100644 (file)
index 0000000..dbbc0d9
--- /dev/null
@@ -0,0 +1,31 @@
+This is Debian GNU/Linux's prepackaged version of Algorithm::Diff This
+is a perl library for finding Longest Common Sequences on textual
+information.
+
+Michael Alan Dorman originally built this package.  It was later maintained
+by Florian Weimer <fw@deneb.enyo.de> and is now taken care of by the Debian
+Perl Group.
+
+The original sources should always be available from the Comprehensive
+Perl Archive Network (CPAN): http://www.cpan.org/modules/by-module/Algorithm/
+
+The only change for the Debian package was the addition of the debian/
+files.
+
+The Algorithm::Diff copyright is as follows:
+
+| Parts Copyright (c) 2000-2004 Ned Konz.  All rights reserved.
+| Parts by Tye McQueen.
+|
+| This program is free software; you can redistribute it and/or modify it
+| under the same terms as Perl.
+
+Perl is distributed under your choice of the GNU General Public License or
+the Artistic License.  On Debian GNU/Linux systems, the complete text of the
+GNU General Public License can be found in `/usr/share/common-licenses/GPL'
+and the Artistic Licence in `/usr/share/common-licenses/Artistic'.
+
+cdiff.pl, diff.pl, diffnw.pl:
+ Copyright 1998 M-J. Dominus. (mjd-perl-diff@plover.com)
+ This program is free software; you can redistribute it and/or modify it
+ under the same terms as Perl.
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/rules b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/rules
new file mode 100755 (executable)
index 0000000..12bb149
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/make -f
+# This debian/rules file is provided as a template for normal perl
+# packages. It was created by Marc Brockschmidt <marc@dch-faq.de> for
+# the Debian Perl Group (http://pkg-perl.alioth.debian.org/) but may
+# be used freely wherever it is useful.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# If set to a true value then MakeMaker's prompt function will
+# always return the default without waiting for user input.
+export PERL_MM_USE_DEFAULT=1
+
+PACKAGE=$(shell dh_listpackages)
+
+ifndef PERL
+PERL = /usr/bin/perl
+endif
+
+TMP     =$(CURDIR)/debian/$(PACKAGE)
+
+build: build-stamp
+build-stamp:
+       dh_testdir
+
+       $(PERL) Makefile.PL INSTALLDIRS=vendor
+       $(MAKE)
+       $(MAKE) test
+
+       touch $@
+
+clean:
+       dh_testdir
+       dh_testroot
+
+       dh_clean build-stamp install-stamp
+       [ ! -f Makefile ] || $(MAKE) realclean
+
+install: install-stamp
+install-stamp: build-stamp
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+
+       $(MAKE) install DESTDIR=$(TMP) PREFIX=/usr
+
+       # remove scripts, we install them as examples later
+       $(RM) -fv $(TMP)/usr/share/perl5/Algorithm/*.pl
+
+       [ ! -d $(TMP)/usr/lib/perl5 ] || rmdir --ignore-fail-on-non-empty --parents --verbose $(TMP)/usr/lib/perl5
+
+       touch $@
+
+binary-arch:
+# We have nothing to do here for an architecture-independent package
+
+binary-indep: build install
+       dh_testdir
+       dh_testroot
+       dh_installexamples *.pl
+       dh_installdocs README
+       dh_installchangelogs Changes
+       dh_perl
+       dh_compress
+       dh_fixperms
+       dh_installdeb
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+source diff:
+       @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/watch b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/debian/watch
new file mode 100644 (file)
index 0000000..02fa773
--- /dev/null
@@ -0,0 +1,4 @@
+version=3
+# http://search.cpan.org/dist/Algorithm-Diff/ doesn't carry current versions
+options=uversionmangle=s/\.(\d\d)(\d\d)/.$1.$2/ \
+http://www.cpan.org/modules/by-module/Algorithm/Algorithm-Diff-([^-]+)\.tar\.gz
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/diff.pl b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/diff.pl
new file mode 100644 (file)
index 0000000..9bddb15
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+#
+# `Diff' program in Perl
+# Copyright 1998 M-J. Dominus. (mjd-perl-diff@plover.com)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+#
+
+use Algorithm::Diff qw(diff);
+
+bag("Usage: $0 oldfile newfile") unless @ARGV == 2;
+
+my ($file1, $file2) = @ARGV;
+
+# -f $file1 or bag("$file1: not a regular file");
+# -f $file2 or bag("$file2: not a regular file");
+
+-T $file1 or bag("$file1: binary");
+-T $file2 or bag("$file2: binary");
+
+open (F1, $file1) or bag("Couldn't open $file1: $!");
+open (F2, $file2) or bag("Couldn't open $file2: $!");
+chomp(@f1 = <F1>);
+close F1;
+chomp(@f2 = <F2>);
+close F2;
+
+$diffs = diff(\@f1, \@f2);
+exit 0 unless @$diffs;
+
+foreach $chunk (@$diffs) {
+  
+  foreach $line (@$chunk) {
+    my ($sign, $lineno, $text) = @$line;
+    printf "%4d$sign %s\n", $lineno+1, $text;
+  }
+  print "--------\n";
+}
+exit 1;
+
+sub bag {
+  my $msg = shift;
+  $msg .= "\n";
+  warn $msg;
+  exit 2;
+}
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/diffnew.pl b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/diffnew.pl
new file mode 100644 (file)
index 0000000..492e52b
--- /dev/null
@@ -0,0 +1,528 @@
+#!/usr/bin/perl
+#
+# `Diff' program in Perl
+# Copyright 1998 M-J. Dominus. (mjd-perl-diff@plover.com)
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+#
+# Altered to output in `context diff' format (but without context)
+# September 1998 Christian Murphy (cpm@muc.de)
+#
+# Context lines feature added
+# Unified, "Old" (Standard UNIX), Ed diff added September 1998
+# Reverse_Ed (-f option) added March 1999
+# Amir D. Karger (karger@bead.aecom.yu.edu)
+#
+# Modular functions integrated into program
+# February 1999 M-J. Dominus (mjd-perl-diff@plover.com)
+#
+# In this file, "item" usually means "line of text", and "item number" usually
+# means "line number". But theoretically the code could be used more generally
+use strict;
+use Algorithm::Diff qw(diff);
+
+# GLOBAL VARIABLES  ####
+# After we've read up to a certain point in each file, the number of items
+# we've read from each file will differ by $FLD (could be 0)
+my $File_Length_Difference = 0;
+
+#ed diff outputs hunks *backwards*, so we need to save hunks when doing ed diff
+my @Ed_Hunks = ();
+########################
+
+my $usage = << "ENDUSAGE";
+Usage: $0 [{-c | -C lines -e | -f | -u | -U lines}] oldfile newfile
+    -c do a context diff with 3 lines of context
+    -C do a context diff with 'lines' lines of context (implies -c)
+    -e create a script for the ed editor to change oldfile to newfile
+    -f like -e but in reverse order
+    -u do a unified diff with 3 lines of context
+    -U do a unified diff with 'lines' lines of context (implies -u)
+    -q report only whether or not the files differ
+
+By default it will do an "old-style" diff, with output like UNIX diff
+ENDUSAGE
+
+my $Context_Lines = 0; # lines of context to print. 0 for old-style diff
+my $Diff_Type = "OLD"; # by default, do standard UNIX diff
+my ($opt_c, $opt_u, $opt_e, $opt_f, $opt_q);
+while ($ARGV[0] =~ /^-/) {
+  my $opt = shift;
+  last if $opt eq '--';
+  if ($opt =~ /^-C(.*)/) {
+    $Context_Lines = $1 || shift;
+    $opt_c = 1;
+    $Diff_Type = "CONTEXT";
+  } elsif ($opt =~ /^-c$/) {
+    $Context_Lines = 3;
+    $opt_c = 1;
+    $Diff_Type = "CONTEXT";
+  } elsif ($opt =~ /^-e$/) {
+    $opt_e = 1;
+    $Diff_Type = "ED";
+  } elsif ($opt =~ /^-f$/) {
+    $opt_f = 1;
+    $Diff_Type = "REVERSE_ED";
+  } elsif ($opt =~ /^-U(.*)$/) {
+    $Context_Lines = $1 || shift;
+    $opt_u = 1;
+    $Diff_Type = "UNIFIED";
+  } elsif ($opt =~ /^-u$/) {
+    $Context_Lines = 3;
+    $opt_u = 1;
+    $Diff_Type = "UNIFIED";
+  } elsif ($opt =~ /^-q$/) {
+    $Context_Lines = 0;
+    $opt_q = 1;
+    $opt_e = 1;
+    $Diff_Type = "ED";
+  } else {
+    $opt =~ s/^-//;
+    bag("Illegal option -- $opt");
+  }
+}
+
+if ($opt_q and grep($_,($opt_c, $opt_f, $opt_u)) > 1) {
+    bag("Combining -q with other options is nonsensical");
+}
+
+if (grep($_,($opt_c, $opt_e, $opt_f, $opt_u)) > 1) {
+    bag("Only one of -c, -u, -f, -e are allowed");
+}
+
+bag($usage) unless @ARGV == 2;
+
+######## DO THE DIFF!
+my ($file1, $file2) = @ARGV;
+
+my ($char1, $char2); # string to print before file names
+if ($Diff_Type eq "CONTEXT") {
+    $char1 = '*' x 3; $char2 = '-' x 3;
+} elsif ($Diff_Type eq "UNIFIED") {
+    $char1 = '-' x 3; $char2 = '+' x 3;
+}
+
+open (F1, $file1) or bag("Couldn't open $file1: $!");
+open (F2, $file2) or bag("Couldn't open $file2: $!");
+my (@f1, @f2);
+chomp(@f1 = <F1>);
+close F1;
+chomp(@f2 = <F2>);
+close F2;
+
+# diff yields lots of pieces, each of which is basically a Block object
+my $diffs = diff(\@f1, \@f2);
+exit 0 unless @$diffs;
+
+if ($opt_q and @$diffs) {
+    print "Files $file1 and $file2 differ\n";
+    exit 1;
+}
+
+if ($Diff_Type =~ /UNIFIED|CONTEXT/) {
+    my @st = stat($file1);
+    my $MTIME = 9;
+    print "$char1 $file1\t", scalar localtime($st[$MTIME]), "\n";
+    @st = stat($file2);
+    print "$char2 $file2\t", scalar localtime($st[$MTIME]), "\n";
+}
+
+my ($hunk,$oldhunk);
+# Loop over hunks. If a hunk overlaps with the last hunk, join them.
+# Otherwise, print out the old one.
+foreach my $piece (@$diffs) {
+    $hunk = new Hunk ($piece, $Context_Lines);
+    next unless $oldhunk; # first time through
+
+    # Don't need to check for overlap if blocks have no context lines
+    if ($Context_Lines && $hunk->does_overlap($oldhunk)) {
+       $hunk->prepend_hunk($oldhunk);
+    } else {
+       $oldhunk->output_diff(\@f1, \@f2, $Diff_Type);
+    }
+
+} continue {
+    $oldhunk = $hunk;
+}
+
+# print the last hunk
+$oldhunk->output_diff(\@f1, \@f2, $Diff_Type);
+
+# Print hunks backwards if we're doing an ed diff
+map {$_->output_ed_diff(\@f1, \@f2, $Diff_Type)} @Ed_Hunks if @Ed_Hunks;
+
+exit 1;
+# END MAIN PROGRAM
+
+sub bag {
+  my $msg = shift;
+  $msg .= "\n";
+  warn $msg;
+  exit 2;
+}
+
+########
+# Package Hunk. A Hunk is a group of Blocks which overlap because of the
+# context surrounding each block. (So if we're not using context, every
+# hunk will contain one block.)
+{
+package Hunk;
+
+sub new {
+# Arg1 is output from &LCS::diff (which corresponds to one Block)
+# Arg2 is the number of items (lines, e.g.,) of context around each block
+#
+# This subroutine changes $File_Length_Difference
+#
+# Fields in a Hunk:
+# blocks      - a list of Block objects
+# start       - index in file 1 where first block of the hunk starts
+# end         - index in file 1 where last block of the hunk ends
+#
+# Variables:
+# before_diff - how much longer file 2 is than file 1 due to all hunks
+#               until but NOT including this one
+# after_diff  - difference due to all hunks including this one
+    my ($class, $piece, $context_items) = @_;
+
+    my $block = new Block ($piece); # this modifies $FLD!
+
+    my $before_diff = $File_Length_Difference; # BEFORE this hunk
+    my $after_diff = $before_diff + $block->{"length_diff"};
+    $File_Length_Difference += $block->{"length_diff"};
+
+    # @remove_array and @insert_array hold the items to insert and remove
+    # Save the start & beginning of each array. If the array doesn't exist
+    # though (e.g., we're only adding items in this block), then figure
+    # out the line number based on the line number of the other file and
+    # the current difference in file lenghts
+    my @remove_array = $block->remove;
+    my @insert_array = $block->insert;
+    my ($a1, $a2, $b1, $b2, $start1, $start2, $end1, $end2);
+    $a1 = @remove_array ? $remove_array[0 ]->{"item_no"} : -1;
+    $a2 = @remove_array ? $remove_array[-1]->{"item_no"} : -1;
+    $b1 = @insert_array ? $insert_array[0 ]->{"item_no"} : -1;
+    $b2 = @insert_array ? $insert_array[-1]->{"item_no"} : -1;
+
+    $start1 = $a1 == -1 ? $b1 - $before_diff : $a1;
+    $end1   = $a2 == -1 ? $b2 - $after_diff  : $a2;
+    $start2 = $b1 == -1 ? $a1 + $before_diff : $b1;
+    $end2   = $b2 == -1 ? $a2 + $after_diff  : $b2;
+
+    # At first, a hunk will have just one Block in it
+    my $hunk = {
+           "start1" => $start1,
+           "start2" => $start2,
+           "end1" => $end1,
+           "end2" => $end2,
+           "blocks" => [$block],
+              };
+    bless $hunk, $class;
+
+    $hunk->flag_context($context_items);
+
+    return $hunk;
+}
+
+# Change the "start" and "end" fields to note that context should be added
+# to this hunk
+sub flag_context {
+    my ($hunk, $context_items) = @_;
+    return unless $context_items; # no context
+
+    # add context before
+    my $start1 = $hunk->{"start1"};
+    my $num_added = $context_items > $start1 ? $start1 : $context_items;
+    $hunk->{"start1"} -= $num_added;
+    $hunk->{"start2"} -= $num_added;
+
+    # context after
+    my $end1 = $hunk->{"end1"};
+    $num_added = ($end1+$context_items > $#f1) ?
+                  $#f1 - $end1 :
+                  $context_items;
+    $hunk->{"end1"} += $num_added;
+    $hunk->{"end2"} += $num_added;
+}
+
+# Is there an overlap between hunk arg0 and old hunk arg1?
+# Note: if end of old hunk is one less than beginning of second, they overlap
+sub does_overlap {
+    my ($hunk, $oldhunk) = @_;
+    return "" unless $oldhunk; # first time through, $oldhunk is empty
+
+    # Do I actually need to test both?
+    return ($hunk->{"start1"} - $oldhunk->{"end1"} <= 1 ||
+            $hunk->{"start2"} - $oldhunk->{"end2"} <= 1);
+}
+
+# Prepend hunk arg1 to hunk arg0
+# Note that arg1 isn't updated! Only arg0 is.
+sub prepend_hunk {
+    my ($hunk, $oldhunk) = @_;
+
+    $hunk->{"start1"} = $oldhunk->{"start1"};
+    $hunk->{"start2"} = $oldhunk->{"start2"};
+
+    unshift (@{$hunk->{"blocks"}}, @{$oldhunk->{"blocks"}});
+}
+
+
+# DIFF OUTPUT ROUTINES. THESE ROUTINES CONTAIN DIFF FORMATTING INFO...
+sub output_diff {
+# First arg is the current hunk of course
+# Next args are refs to the files
+# last arg is type of diff
+    my $diff_type = $_[-1];
+    my %funchash  = ("OLD"        => \&output_old_diff,
+                     "CONTEXT"    => \&output_context_diff,
+                    "ED"         => \&store_ed_diff,
+                    "REVERSE_ED" => \&output_ed_diff,
+                     "UNIFIED"    => \&output_unified_diff,
+                   );
+    if (exists $funchash{$diff_type}) {
+        &{$funchash{$diff_type}}(@_); # pass in all args
+    } else {die "unknown diff type $diff_type"}
+}
+
+sub output_old_diff {
+# Note that an old diff can't have any context. Therefore, we know that
+# there's only one block in the hunk.
+    my ($hunk, $fileref1, $fileref2) = @_;
+    my %op_hash = ('+' => 'a', '-' => 'd', '!' => 'c');
+
+    my @blocklist = @{$hunk->{"blocks"}};
+    warn ("Expecting one block in an old diff hunk!") if scalar @blocklist != 1;
+    my $block = $blocklist[0];
+    my $op = $block->op; # +, -, or !
+
+    # Calculate item number range.
+    # old diff range is just like a context diff range, except the ranges
+    # are on one line with the action between them.
+    my $range1 = $hunk->context_range(1);
+    my $range2 = $hunk->context_range(2);
+    my $action = $op_hash{$op} || warn "unknown op $op";
+    print "$range1$action$range2\n";
+
+    # If removing anything, just print out all the remove lines in the hunk
+    # which is just all the remove lines in the block
+    if ($block->remove) {
+       my @outlist = @$fileref1[$hunk->{"start1"}..$hunk->{"end1"}];
+       map {$_ = "< $_\n"} @outlist; # all lines will be '< text\n'
+       print @outlist;
+    }
+
+    print "---\n" if $op eq '!'; # only if inserting and removing
+    if ($block->insert) {
+       my @outlist = @$fileref2[$hunk->{"start2"}..$hunk->{"end2"}];
+       map {$_ = "> $_\n"} @outlist; # all lines will be '> text\n'
+       print @outlist;
+    }
+}
+
+sub output_unified_diff {
+    my ($hunk, $fileref1, $fileref2) = @_;
+    my @blocklist;
+
+    # Calculate item number range.
+    my $range1 = $hunk->unified_range(1);
+    my $range2 = $hunk->unified_range(2);
+    print "@@ -$range1 +$range2 @@\n";
+
+    # Outlist starts containing the hunk of file 1.
+    # Removing an item just means putting a '-' in front of it.
+    # Inserting an item requires getting it from file2 and splicing it in.
+    #    We splice in $num_added items. Remove blocks use $num_added because
+    # splicing changed the length of outlist.
+    #    We remove $num_removed items. Insert blocks use $num_removed because
+    # their item numbers---corresponding to positions in file *2*--- don't take
+    # removed items into account.
+    my $low = $hunk->{"start1"};
+    my $hi = $hunk->{"end1"};
+    my ($num_added, $num_removed) = (0,0);
+    my @outlist = @$fileref1[$low..$hi];
+    map {s/^/ /} @outlist; # assume it's just context
+
+    foreach my $block (@{$hunk->{"blocks"}}) {
+       foreach my $item ($block->remove) {
+           my $op = $item->{"sign"}; # -
+           my $offset = $item->{"item_no"} - $low + $num_added;
+           $outlist[$offset] =~ s/^ /$op/;
+           $num_removed++;
+       }
+       foreach my $item ($block->insert) {
+           my $op = $item->{"sign"}; # +
+           my $i = $item->{"item_no"};
+           my $offset = $i - $hunk->{"start2"} + $num_removed;
+           splice(@outlist,$offset,0,"$op$$fileref2[$i]");
+           $num_added++;
+       }
+    }
+
+    map {s/$/\n/} @outlist; # add \n's
+    print @outlist;
+
+}
+
+sub output_context_diff {
+    my ($hunk, $fileref1, $fileref2) = @_;
+    my @blocklist;
+
+    print "***************\n";
+    # Calculate item number range.
+    my $range1 = $hunk->context_range(1);
+    my $range2 = $hunk->context_range(2);
+
+    # Print out file 1 part for each block in context diff format if there are
+    # any blocks that remove items
+    print "*** $range1 ****\n";
+    my $low = $hunk->{"start1"};
+    my $hi  = $hunk->{"end1"};
+    if (@blocklist = grep {$_->remove} @{$hunk->{"blocks"}}) {
+       my @outlist = @$fileref1[$low..$hi];
+       map {s/^/  /} @outlist; # assume it's just context
+       foreach my $block (@blocklist) {
+           my $op = $block->op; # - or !
+           foreach my $item ($block->remove) {
+               $outlist[$item->{"item_no"} - $low] =~ s/^ /$op/;
+           }
+       }
+       map {s/$/\n/} @outlist; # add \n's
+       print @outlist;
+    }
+
+    print "--- $range2 ----\n";
+    $low = $hunk->{"start2"};
+    $hi  = $hunk->{"end2"};
+    if (@blocklist = grep {$_->insert} @{$hunk->{"blocks"}}) {
+       my @outlist = @$fileref2[$low..$hi];
+       map {s/^/  /} @outlist; # assume it's just context
+       foreach my $block (@blocklist) {
+           my $op = $block->op; # + or !
+           foreach my $item ($block->insert) {
+               $outlist[$item->{"item_no"} - $low] =~ s/^ /$op/;
+           }
+       }
+       map {s/$/\n/} @outlist; # add \n's
+       print @outlist;
+    }
+}
+
+sub store_ed_diff {
+# ed diff prints out diffs *backwards*. So save them while we're generating
+# them, then print them out at the end
+    my $hunk = shift;
+    unshift @Ed_Hunks, $hunk;
+}
+
+sub output_ed_diff {
+# This sub is used for ed ('diff -e') OR reverse_ed ('diff -f').
+# last arg is type of diff
+    my $diff_type = $_[-1];
+    my ($hunk, $fileref1, $fileref2) = @_;
+    my %op_hash = ('+' => 'a', '-' => 'd', '!' => 'c');
+
+    # Can't be any context for this kind of diff, so each hunk has one block
+    my @blocklist = @{$hunk->{"blocks"}};
+    warn ("Expecting one block in an ed diff hunk!") if scalar @blocklist != 1;
+    my $block = $blocklist[0];
+    my $op = $block->op; # +, -, or !
+
+    # Calculate item number range.
+    # old diff range is just like a context diff range, except the ranges
+    # are on one line with the action between them.
+    my $range1 = $hunk->context_range(1);
+    $range1 =~ s/,/ / if $diff_type eq "REVERSE_ED";
+    my $action = $op_hash{$op} || warn "unknown op $op";
+    print ($diff_type eq "ED" ? "$range1$action\n" : "$action$range1\n");
+
+    if ($block->insert) {
+       my @outlist = @$fileref2[$hunk->{"start2"}..$hunk->{"end2"}];
+       map {s/$/\n/} @outlist; # add \n's
+       print @outlist;
+       print ".\n"; # end of ed 'c' or 'a' command
+    }
+}
+
+sub context_range {
+# Generate a range of item numbers to print. Only print 1 number if the range
+# has only one item in it. Otherwise, it's 'start,end'
+# Flag is the number of the file (1 or 2)
+    my ($hunk, $flag) = @_;
+    my ($start, $end) = ($hunk->{"start$flag"},$hunk->{"end$flag"});
+    $start++; $end++;  # index from 1, not zero
+    my $range = ($start < $end) ? "$start,$end" : $end;
+    return $range;
+}
+
+sub unified_range {
+# Generate a range of item numbers to print for unified diff
+# Print number where block starts, followed by number of lines in the block
+# (don't print number of lines if it's 1)
+    my ($hunk, $flag) = @_;
+    my ($start, $end) = ($hunk->{"start$flag"},$hunk->{"end$flag"});
+    $start++; $end++;  # index from 1, not zero
+    my $length = $end - $start + 1;
+    my $first = $length < 2 ? $end : $start; # strange, but correct...
+    my $range = $length== 1 ? $first : "$first,$length";
+    return $range;
+}
+} # end Package Hunk
+
+########
+# Package Block. A block is an operation removing, adding, or changing
+# a group of items. Basically, this is just a list of changes, where each
+# change adds or deletes a single item.
+# (Change could be a separate class, but it didn't seem worth it)
+{
+package Block;
+sub new {
+# Input is a chunk from &Algorithm::LCS::diff
+# Fields in a block:
+# length_diff - how much longer file 2 is than file 1 due to this block
+# Each change has:
+# sign        - '+' for insert, '-' for remove
+# item_no     - number of the item in the file (e.g., line number)
+# We don't bother storing the text of the item
+#
+    my ($class,$chunk) = @_;
+    my @changes = ();
+
+# This just turns each change into a hash.
+    foreach my $item (@$chunk) {
+       my ($sign, $item_no, $text) = @$item;
+       my $hashref = {"sign" => $sign, "item_no" => $item_no};
+       push @changes, $hashref;
+    }
+
+    my $block = { "changes" => \@changes };
+    bless $block, $class;
+
+    $block->{"length_diff"} = $block->insert - $block->remove;
+    return $block;
+}
+
+
+# LOW LEVEL FUNCTIONS
+sub op {
+# what kind of block is this?
+    my $block = shift;
+    my $insert = $block->insert;
+    my $remove = $block->remove;
+
+    $remove && $insert and return '!';
+    $remove and return '-';
+    $insert and return '+';
+    warn "unknown block type";
+    return '^'; # context block
+}
+
+# Returns a list of the changes in this block that remove items
+# (or the number of removals if called in scalar context)
+sub remove { return grep {$_->{"sign"} eq '-'} @{shift->{"changes"}}; }
+
+# Returns a list of the changes in this block that insert items
+sub insert { return grep {$_->{"sign"} eq '+'} @{shift->{"changes"}}; }
+
+} # end of package Block
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/htmldiff.pl b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/htmldiff.pl
new file mode 100644 (file)
index 0000000..fdc8102
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/perl -w
+# diffs two files and writes an HTML output file.
+use strict;
+use CGI qw(:standard :html3);
+use Algorithm::Diff 'traverse_sequences';
+use Text::Tabs;
+
+my ( @a, @b );
+
+# Take care of whitespace.
+sub preprocess
+{
+       my $arrayRef = shift;
+       chomp(@$arrayRef);
+       @$arrayRef = expand(@$arrayRef);
+}
+
+# This will be called with both lines are the same
+sub match
+{
+       my ( $ia, $ib ) = @_;
+       print pre( $a[$ia] ), "\n";
+}
+
+# This will be called when there is a line in A that isn't in B
+sub only_a
+{
+       my ( $ia, $ib ) = @_;
+       print pre( { -class => 'onlyA' }, $a[$ia] ), "\n";
+}
+
+# This will be called when there is a line in B that isn't in A
+sub only_b
+{
+       my ( $ia, $ib ) = @_;
+       print pre( { -class => 'onlyB' }, $b[$ib] ), "\n";
+}
+
+# MAIN PROGRAM
+
+# Check for two arguments.
+print "usage: $0 file1 file2 > diff.html\n" if @ARGV != 2;
+
+$tabstop = 4;    # For Text::Tabs
+
+# Read each file into an array.
+open FH, $ARGV[0];
+@a = <FH>;
+close FH;
+
+open FH, $ARGV[1];
+@b = <FH>;
+close FH;
+
+# Expand whitespace
+preprocess( \@a );
+preprocess( \@b );
+
+# inline style
+my $style = <<EOS;
+       PRE {
+               margin-left: 24pt; 
+               font-size: 12pt;
+           font-family: Courier, monospaced;
+               white-space: pre
+    }
+       PRE.onlyA { color: red }
+       PRE.onlyB { color: blue }
+EOS
+
+# Print out the starting HTML
+print
+
+  # header(),
+  start_html(
+       {
+               -title => "$ARGV[0] vs. $ARGV[1]",
+               -style => { -code => $style }
+       }
+  ),
+  h1(
+       { -style => 'margin-left: 24pt' },
+       span( { -style => 'color: red' }, $ARGV[0] ),
+       span(" <i>vs.</i> "),
+       span( { -style => 'color: blue' }, $ARGV[1] )
+  ),
+  "\n";
+
+# And compare the arrays
+traverse_sequences(
+       \@a,    # first sequence
+       \@b,    # second sequence
+       {
+               MATCH     => \&match,     # callback on identical lines
+               DISCARD_A => \&only_a,    # callback on A-only
+               DISCARD_B => \&only_b,    # callback on B-only
+       }
+);
+
+print end_html();
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/lib/Algorithm/Diff.pm b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/lib/Algorithm/Diff.pm
new file mode 100644 (file)
index 0000000..c3ceead
--- /dev/null
@@ -0,0 +1,1713 @@
+package Algorithm::Diff;
+# Skip to first "=head" line for documentation.
+use strict;
+
+use integer;    # see below in _replaceNextLargerWith() for mod to make
+                # if you don't use this
+use vars qw( $VERSION @EXPORT_OK );
+$VERSION = 1.19_02;
+#          ^ ^^ ^^-- Incremented at will
+#          | \+----- Incremented for non-trivial changes to features
+#          \-------- Incremented for fundamental changes
+require Exporter;
+*import    = \&Exporter::import;
+@EXPORT_OK = qw(
+    prepare LCS LCSidx LCS_length
+    diff sdiff compact_diff
+    traverse_sequences traverse_balanced
+);
+
+# McIlroy-Hunt diff algorithm
+# Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com>
+# by Ned Konz, perl@bike-nomad.com
+# Updates by Tye McQueen, http://perlmonks.org/?node=tye
+
+# Create a hash that maps each element of $aCollection to the set of
+# positions it occupies in $aCollection, restricted to the elements
+# within the range of indexes specified by $start and $end.
+# The fourth parameter is a subroutine reference that will be called to
+# generate a string to use as a key.
+# Additional parameters, if any, will be passed to this subroutine.
+#
+# my $hashRef = _withPositionsOfInInterval( \@array, $start, $end, $keyGen );
+
+sub _withPositionsOfInInterval
+{
+    my $aCollection = shift;    # array ref
+    my $start       = shift;
+    my $end         = shift;
+    my $keyGen      = shift;
+    my %d;
+    my $index;
+    for ( $index = $start ; $index <= $end ; $index++ )
+    {
+        my $element = $aCollection->[$index];
+        my $key = &$keyGen( $element, @_ );
+        if ( exists( $d{$key} ) )
+        {
+            unshift ( @{ $d{$key} }, $index );
+        }
+        else
+        {
+            $d{$key} = [$index];
+        }
+    }
+    return wantarray ? %d : \%d;
+}
+
+# Find the place at which aValue would normally be inserted into the
+# array. If that place is already occupied by aValue, do nothing, and
+# return undef. If the place does not exist (i.e., it is off the end of
+# the array), add it to the end, otherwise replace the element at that
+# point with aValue.  It is assumed that the array's values are numeric.
+# This is where the bulk (75%) of the time is spent in this module, so
+# try to make it fast!
+
+sub _replaceNextLargerWith
+{
+    my ( $array, $aValue, $high ) = @_;
+    $high ||= $#$array;
+
+    # off the end?
+    if ( $high == -1 || $aValue > $array->[-1] )
+    {
+        push ( @$array, $aValue );
+        return $high + 1;
+    }
+
+    # binary search for insertion point...
+    my $low = 0;
+    my $index;
+    my $found;
+    while ( $low <= $high )
+    {
+        $index = ( $high + $low ) / 2;
+
+        # $index = int(( $high + $low ) / 2);  # without 'use integer'
+        $found = $array->[$index];
+
+        if ( $aValue == $found )
+        {
+            return undef;
+        }
+        elsif ( $aValue > $found )
+        {
+            $low = $index + 1;
+        }
+        else
+        {
+            $high = $index - 1;
+        }
+    }
+
+    # now insertion point is in $low.
+    $array->[$low] = $aValue;    # overwrite next larger
+    return $low;
+}
+
+# This method computes the longest common subsequence in $a and $b.
+
+# Result is array or ref, whose contents is such that
+#   $a->[ $i ] == $b->[ $result[ $i ] ]
+# foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined.
+
+# An additional argument may be passed; this is a hash or key generating
+# function that should return a string that uniquely identifies the given
+# element.  It should be the case that if the key is the same, the elements
+# will compare the same. If this parameter is undef or missing, the key
+# will be the element as a string.
+
+# By default, comparisons will use "eq" and elements will be turned into keys
+# using the default stringizing operator '""'.
+
+# Additional parameters, if any, will be passed to the key generation
+# routine.
+
+sub _longestCommonSubsequence
+{
+    my $a        = shift;    # array ref or hash ref
+    my $b        = shift;    # array ref or hash ref
+    my $counting = shift;    # scalar
+    my $keyGen   = shift;    # code ref
+    my $compare;             # code ref
+
+    if ( ref($a) eq 'HASH' )
+    {                        # prepared hash must be in $b
+        my $tmp = $b;
+        $b = $a;
+        $a = $tmp;
+    }
+
+    # Check for bogus (non-ref) argument values
+    if ( !ref($a) || !ref($b) )
+    {
+        my @callerInfo = caller(1);
+        die 'error: must pass array or hash references to ' . $callerInfo[3];
+    }
+
+    # set up code refs
+    # Note that these are optimized.
+    if ( !defined($keyGen) )    # optimize for strings
+    {
+        $keyGen = sub { $_[0] };
+        $compare = sub { my ( $a, $b ) = @_; $a eq $b };
+    }
+    else
+    {
+        $compare = sub {
+            my $a = shift;
+            my $b = shift;
+            &$keyGen( $a, @_ ) eq &$keyGen( $b, @_ );
+        };
+    }
+
+    my ( $aStart, $aFinish, $matchVector ) = ( 0, $#$a, [] );
+    my ( $prunedCount, $bMatches ) = ( 0, {} );
+
+    if ( ref($b) eq 'HASH' )    # was $bMatches prepared for us?
+    {
+        $bMatches = $b;
+    }
+    else
+    {
+        my ( $bStart, $bFinish ) = ( 0, $#$b );
+
+        # First we prune off any common elements at the beginning
+        while ( $aStart <= $aFinish
+            and $bStart <= $bFinish
+            and &$compare( $a->[$aStart], $b->[$bStart], @_ ) )
+        {
+            $matchVector->[ $aStart++ ] = $bStart++;
+            $prunedCount++;
+        }
+
+        # now the end
+        while ( $aStart <= $aFinish
+            and $bStart <= $bFinish
+            and &$compare( $a->[$aFinish], $b->[$bFinish], @_ ) )
+        {
+            $matchVector->[ $aFinish-- ] = $bFinish--;
+            $prunedCount++;
+        }
+
+        # Now compute the equivalence classes of positions of elements
+        $bMatches =
+          _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ );
+    }
+    my $thresh = [];
+    my $links  = [];
+
+    my ( $i, $ai, $j, $k );
+    for ( $i = $aStart ; $i <= $aFinish ; $i++ )
+    {
+        $ai = &$keyGen( $a->[$i], @_ );
+        if ( exists( $bMatches->{$ai} ) )
+        {
+            $k = 0;
+            for $j ( @{ $bMatches->{$ai} } )
+            {
+
+                # optimization: most of the time this will be true
+                if ( $k and $thresh->[$k] > $j and $thresh->[ $k - 1 ] < $j )
+                {
+                    $thresh->[$k] = $j;
+                }
+                else
+                {
+                    $k = _replaceNextLargerWith( $thresh, $j, $k );
+                }
+
+                # oddly, it's faster to always test this (CPU cache?).
+                if ( defined($k) )
+                {
+                    $links->[$k] =
+                      [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];
+                }
+            }
+        }
+    }
+
+    if (@$thresh)
+    {
+        return $prunedCount + @$thresh if $counting;
+        for ( my $link = $links->[$#$thresh] ; $link ; $link = $link->[0] )
+        {
+            $matchVector->[ $link->[1] ] = $link->[2];
+        }
+    }
+    elsif ($counting)
+    {
+        return $prunedCount;
+    }
+
+    return wantarray ? @$matchVector : $matchVector;
+}
+
+sub traverse_sequences
+{
+    my $a                 = shift;          # array ref
+    my $b                 = shift;          # array ref
+    my $callbacks         = shift || {};
+    my $keyGen            = shift;
+    my $matchCallback     = $callbacks->{'MATCH'} || sub { };
+    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };
+    my $finishedACallback = $callbacks->{'A_FINISHED'};
+    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };
+    my $finishedBCallback = $callbacks->{'B_FINISHED'};
+    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );
+
+    # Process all the lines in @$matchVector
+    my $lastA = $#$a;
+    my $lastB = $#$b;
+    my $bi    = 0;
+    my $ai;
+
+    for ( $ai = 0 ; $ai <= $#$matchVector ; $ai++ )
+    {
+        my $bLine = $matchVector->[$ai];
+        if ( defined($bLine) )    # matched
+        {
+            &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;
+            &$matchCallback( $ai,    $bi++, @_ );
+        }
+        else
+        {
+            &$discardACallback( $ai, $bi, @_ );
+        }
+    }
+
+    # The last entry (if any) processed was a match.
+    # $ai and $bi point just past the last matching lines in their sequences.
+
+    while ( $ai <= $lastA or $bi <= $lastB )
+    {
+
+        # last A?
+        if ( $ai == $lastA + 1 and $bi <= $lastB )
+        {
+            if ( defined($finishedACallback) )
+            {
+                &$finishedACallback( $lastA, @_ );
+                $finishedACallback = undef;
+            }
+            else
+            {
+                &$discardBCallback( $ai, $bi++, @_ ) while $bi <= $lastB;
+            }
+        }
+
+        # last B?
+        if ( $bi == $lastB + 1 and $ai <= $lastA )
+        {
+            if ( defined($finishedBCallback) )
+            {
+                &$finishedBCallback( $lastB, @_ );
+                $finishedBCallback = undef;
+            }
+            else
+            {
+                &$discardACallback( $ai++, $bi, @_ ) while $ai <= $lastA;
+            }
+        }
+
+        &$discardACallback( $ai++, $bi, @_ ) if $ai <= $lastA;
+        &$discardBCallback( $ai, $bi++, @_ ) if $bi <= $lastB;
+    }
+
+    return 1;
+}
+
+sub traverse_balanced
+{
+    my $a                 = shift;              # array ref
+    my $b                 = shift;              # array ref
+    my $callbacks         = shift || {};
+    my $keyGen            = shift;
+    my $matchCallback     = $callbacks->{'MATCH'} || sub { };
+    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };
+    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };
+    my $changeCallback    = $callbacks->{'CHANGE'};
+    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );
+
+    # Process all the lines in match vector
+    my $lastA = $#$a;
+    my $lastB = $#$b;
+    my $bi    = 0;
+    my $ai    = 0;
+    my $ma    = -1;
+    my $mb;
+
+    while (1)
+    {
+
+        # Find next match indices $ma and $mb
+        do {
+            $ma++;
+        } while(
+                $ma <= $#$matchVector
+            &&  !defined $matchVector->[$ma]
+        );
+
+        last if $ma > $#$matchVector;    # end of matchVector?
+        $mb = $matchVector->[$ma];
+
+        # Proceed with discard a/b or change events until
+        # next match
+        while ( $ai < $ma || $bi < $mb )
+        {
+
+            if ( $ai < $ma && $bi < $mb )
+            {
+
+                # Change
+                if ( defined $changeCallback )
+                {
+                    &$changeCallback( $ai++, $bi++, @_ );
+                }
+                else
+                {
+                    &$discardACallback( $ai++, $bi, @_ );
+                    &$discardBCallback( $ai, $bi++, @_ );
+                }
+            }
+            elsif ( $ai < $ma )
+            {
+                &$discardACallback( $ai++, $bi, @_ );
+            }
+            else
+            {
+
+                # $bi < $mb
+                &$discardBCallback( $ai, $bi++, @_ );
+            }
+        }
+
+        # Match
+        &$matchCallback( $ai++, $bi++, @_ );
+    }
+
+    while ( $ai <= $lastA || $bi <= $lastB )
+    {
+        if ( $ai <= $lastA && $bi <= $lastB )
+        {
+
+            # Change
+            if ( defined $changeCallback )
+            {
+                &$changeCallback( $ai++, $bi++, @_ );
+            }
+            else
+            {
+                &$discardACallback( $ai++, $bi, @_ );
+                &$discardBCallback( $ai, $bi++, @_ );
+            }
+        }
+        elsif ( $ai <= $lastA )
+        {
+            &$discardACallback( $ai++, $bi, @_ );
+        }
+        else
+        {
+
+            # $bi <= $lastB
+            &$discardBCallback( $ai, $bi++, @_ );
+        }
+    }
+
+    return 1;
+}
+
+sub prepare
+{
+    my $a       = shift;    # array ref
+    my $keyGen  = shift;    # code ref
+
+    # set up code ref
+    $keyGen = sub { $_[0] } unless defined($keyGen);
+
+    return scalar _withPositionsOfInInterval( $a, 0, $#$a, $keyGen, @_ );
+}
+
+sub LCS
+{
+    my $a = shift;                  # array ref
+    my $b = shift;                  # array ref or hash ref
+    my $matchVector = _longestCommonSubsequence( $a, $b, 0, @_ );
+    my @retval;
+    my $i;
+    for ( $i = 0 ; $i <= $#$matchVector ; $i++ )
+    {
+        if ( defined( $matchVector->[$i] ) )
+        {
+            push ( @retval, $a->[$i] );
+        }
+    }
+    return wantarray ? @retval : \@retval;
+}
+
+sub LCS_length
+{
+    my $a = shift;                          # array ref
+    my $b = shift;                          # array ref or hash ref
+    return _longestCommonSubsequence( $a, $b, 1, @_ );
+}
+
+sub LCSidx
+{
+    my $a= shift @_;
+    my $b= shift @_;
+    my $match= _longestCommonSubsequence( $a, $b, 0, @_ );
+    my @am= grep defined $match->[$_], 0..$#$match;
+    my @bm= @{$match}[@am];
+    return \@am, \@bm;
+}
+
+sub compact_diff
+{
+    my $a= shift @_;
+    my $b= shift @_;
+    my( $am, $bm )= LCSidx( $a, $b, @_ );
+    my @cdiff;
+    my( $ai, $bi )= ( 0, 0 );
+    push @cdiff, $ai, $bi;
+    while( 1 ) {
+        while(  @$am  &&  $ai == $am->[0]  &&  $bi == $bm->[0]  ) {
+            shift @$am;
+            shift @$bm;
+            ++$ai, ++$bi;
+        }
+        push @cdiff, $ai, $bi;
+        last   if  ! @$am;
+        $ai = $am->[0];
+        $bi = $bm->[0];
+        push @cdiff, $ai, $bi;
+    }
+    push @cdiff, 0+@$a, 0+@$b
+        if  $ai < @$a || $bi < @$b;
+    return wantarray ? @cdiff : \@cdiff;
+}
+
+sub diff
+{
+    my $a      = shift;    # array ref
+    my $b      = shift;    # array ref
+    my $retval = [];
+    my $hunk   = [];
+    my $discard = sub {
+        push @$hunk, [ '-', $_[0], $a->[ $_[0] ] ];
+    };
+    my $add = sub {
+        push @$hunk, [ '+', $_[1], $b->[ $_[1] ] ];
+    };
+    my $match = sub {
+        push @$retval, $hunk
+            if 0 < @$hunk;
+        $hunk = []
+    };
+    traverse_sequences( $a, $b,
+        { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add }, @_ );
+    &$match();
+    return wantarray ? @$retval : $retval;
+}
+
+sub sdiff
+{
+    my $a      = shift;    # array ref
+    my $b      = shift;    # array ref
+    my $retval = [];
+    my $discard = sub { push ( @$retval, [ '-', $a->[ $_[0] ], "" ] ) };
+    my $add = sub { push ( @$retval, [ '+', "", $b->[ $_[1] ] ] ) };
+    my $change = sub {
+        push ( @$retval, [ 'c', $a->[ $_[0] ], $b->[ $_[1] ] ] );
+    };
+    my $match = sub {
+        push ( @$retval, [ 'u', $a->[ $_[0] ], $b->[ $_[1] ] ] );
+    };
+    traverse_balanced(
+        $a,
+        $b,
+        {
+            MATCH     => $match,
+            DISCARD_A => $discard,
+            DISCARD_B => $add,
+            CHANGE    => $change,
+        },
+        @_
+    );
+    return wantarray ? @$retval : $retval;
+}
+
+########################################
+my $Root= __PACKAGE__;
+package Algorithm::Diff::_impl;
+use strict;
+
+sub _Idx()  { 0 } # $me->[_Idx]: Ref to array of hunk indices
+            # 1   # $me->[1]: Ref to first sequence
+            # 2   # $me->[2]: Ref to second sequence
+sub _End()  { 3 } # $me->[_End]: Diff between forward and reverse pos
+sub _Same() { 4 } # $me->[_Same]: 1 if pos 1 contains unchanged items
+sub _Base() { 5 } # $me->[_Base]: Added to range's min and max
+sub _Pos()  { 6 } # $me->[_Pos]: Which hunk is currently selected
+sub _Off()  { 7 } # $me->[_Off]: Offset into _Idx for current position
+sub _Min() { -2 } # Added to _Off to get min instead of max+1
+
+sub Die
+{
+    require Carp;
+    Carp::confess( @_ );
+}
+
+sub _ChkPos
+{
+    my( $me )= @_;
+    return   if  $me->[_Pos];
+    my $meth= ( caller(1) )[3];
+    Die( "Called $meth on 'reset' object" );
+}
+
+sub _ChkSeq
+{
+    my( $me, $seq )= @_;
+    return $seq + $me->[_Off]
+        if  1 == $seq  ||  2 == $seq;
+    my $meth= ( caller(1) )[3];
+    Die( "$meth: Invalid sequence number ($seq); must be 1 or 2" );
+}
+
+sub getObjPkg
+{
+    my( $us )= @_;
+    return ref $us   if  ref $us;
+    return $us . "::_obj";
+}
+
+sub new
+{
+    my( $us, $seq1, $seq2, $opts ) = @_;
+    my @args;
+    for( $opts->{keyGen} ) {
+        push @args, $_   if  $_;
+    }
+    for( $opts->{keyGenArgs} ) {
+        push @args, @$_   if  $_;
+    }
+    my $cdif= Algorithm::Diff::compact_diff( $seq1, $seq2, @args );
+    my $same= 1;
+    if(  0 == $cdif->[2]  &&  0 == $cdif->[3]  ) {
+        $same= 0;
+        splice @$cdif, 0, 2;
+    }
+    my @obj= ( $cdif, $seq1, $seq2 );
+    $obj[_End] = (1+@$cdif)/2;
+    $obj[_Same] = $same;
+    $obj[_Base] = 0;
+    my $me = bless \@obj, $us->getObjPkg();
+    $me->Reset( 0 );
+    return $me;
+}
+
+sub Reset
+{
+    my( $me, $pos )= @_;
+    $pos= int( $pos || 0 );
+    $pos += $me->[_End]
+        if  $pos < 0;
+    $pos= 0
+        if  $pos < 0  ||  $me->[_End] <= $pos;
+    $me->[_Pos]= $pos || !1;
+    $me->[_Off]= 2*$pos - 1;
+    return $me;
+}
+
+sub Base
+{
+    my( $me, $base )= @_;
+    my $oldBase= $me->[_Base];
+    $me->[_Base]= 0+$base   if  defined $base;
+    return $oldBase;
+}
+
+sub Copy
+{
+    my( $me, $pos, $base )= @_;
+    my @obj= @$me;
+    my $you= bless \@obj, ref($me);
+    $you->Reset( $pos )   if  defined $pos;
+    $you->Base( $base );
+    return $you;
+}
+
+sub Next {
+    my( $me, $steps )= @_;
+    $steps= 1   if  ! defined $steps;
+    if( $steps ) {
+        my $pos= $me->[_Pos];
+        my $new= $pos + $steps;
+        $new= 0   if  $pos  &&  $new < 0;
+        $me->Reset( $new )
+    }
+    return $me->[_Pos];
+}
+
+sub Prev {
+    my( $me, $steps )= @_;
+    $steps= 1   if  ! defined $steps;
+    my $pos= $me->Next(-$steps);
+    $pos -= $me->[_End]   if  $pos;
+    return $pos;
+}
+
+sub Diff {
+    my( $me )= @_;
+    $me->_ChkPos();
+    return 0   if  $me->[_Same] == ( 1 & $me->[_Pos] );
+    my $ret= 0;
+    my $off= $me->[_Off];
+    for my $seq ( 1, 2 ) {
+        $ret |= $seq
+            if  $me->[_Idx][ $off + $seq + _Min ]
+            <   $me->[_Idx][ $off + $seq ];
+    }
+    return $ret;
+}
+
+sub Min {
+    my( $me, $seq, $base )= @_;
+    $me->_ChkPos();
+    my $off= $me->_ChkSeq($seq);
+    $base= $me->[_Base] if !defined $base;
+    return $base + $me->[_Idx][ $off + _Min ];
+}
+
+sub Max {
+    my( $me, $seq, $base )= @_;
+    $me->_ChkPos();
+    my $off= $me->_ChkSeq($seq);
+    $base= $me->[_Base] if !defined $base;
+    return $base + $me->[_Idx][ $off ] -1;
+}
+
+sub Range {
+    my( $me, $seq, $base )= @_;
+    $me->_ChkPos();
+    my $off = $me->_ChkSeq($seq);
+    if( !wantarray ) {
+        return  $me->[_Idx][ $off ]
+            -   $me->[_Idx][ $off + _Min ];
+    }
+    $base= $me->[_Base] if !defined $base;
+    return  ( $base + $me->[_Idx][ $off + _Min ] )
+        ..  ( $base + $me->[_Idx][ $off ] - 1 );
+}
+
+sub Items {
+    my( $me, $seq )= @_;
+    $me->_ChkPos();
+    my $off = $me->_ChkSeq($seq);
+    if( !wantarray ) {
+        return  $me->[_Idx][ $off ]
+            -   $me->[_Idx][ $off + _Min ];
+    }
+    return
+        @{$me->[$seq]}[
+                $me->[_Idx][ $off + _Min ]
+            ..  ( $me->[_Idx][ $off ] - 1 )
+        ];
+}
+
+sub Same {
+    my( $me )= @_;
+    $me->_ChkPos();
+    return wantarray ? () : 0
+        if  $me->[_Same] != ( 1 & $me->[_Pos] );
+    return $me->Items(1);
+}
+
+my %getName;
+BEGIN {
+    %getName= (
+        same => \&Same,
+        diff => \&Diff,
+        base => \&Base,
+        min  => \&Min,
+        max  => \&Max,
+        range=> \&Range,
+        items=> \&Items, # same thing
+    );
+}
+
+sub Get
+{
+    my $me= shift @_;
+    $me->_ChkPos();
+    my @value;
+    for my $arg (  @_  ) {
+        for my $word (  split ' ', $arg  ) {
+            my $meth;
+            if(     $word !~ /^(-?\d+)?([a-zA-Z]+)([12])?$/
+                ||  not  $meth= $getName{ lc $2 }
+            ) {
+                Die( $Root, ", Get: Invalid request ($word)" );
+            }
+            my( $base, $name, $seq )= ( $1, $2, $3 );
+            push @value, scalar(
+                4 == length($name)
+                    ? $meth->( $me )
+                    : $meth->( $me, $seq, $base )
+            );
+        }
+    }
+    if(  wantarray  ) {
+        return @value;
+    } elsif(  1 == @value  ) {
+        return $value[0];
+    }
+    Die( 0+@value, " values requested from ",
+        $Root, "'s Get in scalar context" );
+}
+
+
+my $Obj= getObjPkg($Root);
+no strict 'refs';
+
+for my $meth (  qw( new getObjPkg )  ) {
+    *{$Root."::".$meth} = \&{$meth};
+    *{$Obj ."::".$meth} = \&{$meth};
+}
+for my $meth (  qw(
+    Next Prev Reset Copy Base Diff
+    Same Items Range Min Max Get
+    _ChkPos _ChkSeq
+)  ) {
+    *{$Obj."::".$meth} = \&{$meth};
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Algorithm::Diff - Compute `intelligent' differences between two files / lists
+
+=head1 SYNOPSIS
+
+    require Algorithm::Diff;
+
+    # This example produces traditional 'diff' output:
+
+    my $diff = Algorithm::Diff->new( \@seq1, \@seq2 );
+
+    $diff->Base( 1 );   # Return line numbers, not indices
+    while(  $diff->Next()  ) {
+        next   if  $diff->Same();
+        my $sep = '';
+        if(  ! $diff->Items(2)  ) {
+            printf "%d,%dd%d\n",
+                $diff->Get(qw( Min1 Max1 Max2 ));
+        } elsif(  ! $diff->Items(1)  ) {
+            printf "%da%d,%d\n",
+                $diff->Get(qw( Max1 Min2 Max2 ));
+        } else {
+            $sep = "---\n";
+            printf "%d,%dc%d,%d\n",
+                $diff->Get(qw( Min1 Max1 Min2 Max2 ));
+        }
+        print "< $_"   for  $diff->Items(1);
+        print $sep;
+        print "> $_"   for  $diff->Items(2);
+    }
+
+
+    # Alternate interfaces:
+
+    use Algorithm::Diff qw(
+        LCS LCS_length LCSidx
+        diff sdiff compact_diff
+        traverse_sequences traverse_balanced );
+
+    @lcs    = LCS( \@seq1, \@seq2 );
+    $lcsref = LCS( \@seq1, \@seq2 );
+    $count  = LCS_length( \@seq1, \@seq2 );
+
+    ( $seq1idxref, $seq2idxref ) = LCSidx( \@seq1, \@seq2 );
+
+
+    # Complicated interfaces:
+
+    @diffs  = diff( \@seq1, \@seq2 );
+
+    @sdiffs = sdiff( \@seq1, \@seq2 );
+
+    @cdiffs = compact_diff( \@seq1, \@seq2 );
+
+    traverse_sequences(
+        \@seq1,
+        \@seq2,
+        {   MATCH     => \&callback1,
+            DISCARD_A => \&callback2,
+            DISCARD_B => \&callback3,
+        },
+        \&key_generator,
+        @extra_args,
+    );
+
+    traverse_balanced(
+        \@seq1,
+        \@seq2,
+        {   MATCH     => \&callback1,
+            DISCARD_A => \&callback2,
+            DISCARD_B => \&callback3,
+            CHANGE    => \&callback4,
+        },
+        \&key_generator,
+        @extra_args,
+    );
+
+
+=head1 INTRODUCTION
+
+(by Mark-Jason Dominus)
+
+I once read an article written by the authors of C<diff>; they said
+that they worked very hard on the algorithm until they found the
+right one.
+
+I think what they ended up using (and I hope someone will correct me,
+because I am not very confident about this) was the `longest common
+subsequence' method.  In the LCS problem, you have two sequences of
+items:
+
+    a b c d f g h j q z
+
+    a b c d e f g i j k r x y z
+
+and you want to find the longest sequence of items that is present in
+both original sequences in the same order.  That is, you want to find
+a new sequence I<S> which can be obtained from the first sequence by
+deleting some items, and from the secend sequence by deleting other
+items.  You also want I<S> to be as long as possible.  In this case I<S>
+is
+
+    a b c d f g j z
+
+From there it's only a small step to get diff-like output:
+
+    e   h i   k   q r x y
+    +   - +   +   - + + +
+
+This module solves the LCS problem.  It also includes a canned function
+to generate C<diff>-like output.
+
+It might seem from the example above that the LCS of two sequences is
+always pretty obvious, but that's not always the case, especially when
+the two sequences have many repeated elements.  For example, consider
+
+    a x b y c z p d q
+    a b c a x b y c z
+
+A naive approach might start by matching up the C<a> and C<b> that
+appear at the beginning of each sequence, like this:
+
+    a x b y c         z p d q
+    a   b   c a b y c z
+
+This finds the common subsequence C<a b c z>.  But actually, the LCS
+is C<a x b y c z>:
+
+          a x b y c z p d q
+    a b c a x b y c z
+
+or
+
+    a       x b y c z p d q
+    a b c a x b y c z
+
+=head1 USAGE
+
+(See also the README file and several example
+scripts include with this module.)
+
+This module now provides an object-oriented interface that uses less
+memory and is easier to use than most of the previous procedural
+interfaces.  It also still provides several exportable functions.  We'll
+deal with these in ascending order of difficulty:  C<LCS>,
+C<LCS_length>, C<LCSidx>, OO interface, C<prepare>, C<diff>, C<sdiff>,
+C<traverse_sequences>, and C<traverse_balanced>.
+
+=head2 C<LCS>
+
+Given references to two lists of items, LCS returns an array containing
+their longest common subsequence.  In scalar context, it returns a
+reference to such a list.
+
+    @lcs    = LCS( \@seq1, \@seq2 );
+    $lcsref = LCS( \@seq1, \@seq2 );
+
+C<LCS> may be passed an optional third parameter; this is a CODE
+reference to a key generation function.  See L</KEY GENERATION
+FUNCTIONS>.
+
+    @lcs    = LCS( \@seq1, \@seq2, \&keyGen, @args );
+    $lcsref = LCS( \@seq1, \@seq2, \&keyGen, @args );
+
+Additional parameters, if any, will be passed to the key generation
+routine.
+
+=head2 C<LCS_length>
+
+This is just like C<LCS> except it only returns the length of the
+longest common subsequence.  This provides a performance gain of about
+9% compared to C<LCS>.
+
+=head2 C<LCSidx>
+
+Like C<LCS> except it returns references to two arrays.  The first array
+contains the indices into @seq1 where the LCS items are located.  The
+second array contains the indices into @seq2 where the LCS items are located.
+
+Therefore, the following three lists will contain the same values:
+
+    my( $idx1, $idx2 ) = LCSidx( \@seq1, \@seq2 );
+    my @list1 = @seq1[ @$idx1 ];
+    my @list2 = @seq2[ @$idx2 ];
+    my @list3 = LCS( \@seq1, \@seq2 );
+
+=head2 C<new>
+
+    $diff = Algorithm::Diffs->new( \@seq1, \@seq2 );
+    $diff = Algorithm::Diffs->new( \@seq1, \@seq2, \%opts );
+
+C<new> computes the smallest set of additions and deletions necessary
+to turn the first sequence into the second and compactly records them
+in the object.
+
+You use the object to iterate over I<hunks>, where each hunk represents
+a contiguous section of items which should be added, deleted, replaced,
+or left unchanged.
+
+=over 4
+
+The following summary of all of the methods looks a lot like Perl code
+but some of the symbols have different meanings:
+
+    [ ]     Encloses optional arguments
+    :       Is followed by the default value for an optional argument
+    |       Separates alternate return results
+
+Method summary:
+
+    $obj        = Algorithm::Diff->new( \@seq1, \@seq2, [ \%opts ] );
+    $pos        = $obj->Next(  [ $count : 1 ] );
+    $revPos     = $obj->Prev(  [ $count : 1 ] );
+    $obj        = $obj->Reset( [ $pos : 0 ] );
+    $copy       = $obj->Copy(  [ $pos, [ $newBase ] ] );
+    $oldBase    = $obj->Base(  [ $newBase ] );
+
+Note that all of the following methods C<die> if used on an object that
+is "reset" (not currently pointing at any hunk).
+
+    $bits       = $obj->Diff(  );
+    @items|$cnt = $obj->Same(  );
+    @items|$cnt = $obj->Items( $seqNum );
+    @idxs |$cnt = $obj->Range( $seqNum, [ $base ] );
+    $minIdx     = $obj->Min(   $seqNum, [ $base ] );
+    $maxIdx     = $obj->Max(   $seqNum, [ $base ] );
+    @values     = $obj->Get(   @names );
+
+Passing in C<undef> for an optional argument is always treated the same
+as if no argument were passed in.
+
+=item C<Next>
+
+    $pos = $diff->Next();    # Move forward 1 hunk
+    $pos = $diff->Next( 2 ); # Move forward 2 hunks
+    $pos = $diff->Next(-5);  # Move backward 5 hunks
+
+C<Next> moves the object to point at the next hunk.  The object starts
+out "reset", which means it isn't pointing at any hunk.  If the object
+is reset, then C<Next()> moves to the first hunk.
+
+C<Next> returns a true value iff the move didn't go past the last hunk.
+So C<Next(0)> will return true iff the object is not reset.
+
+Actually, C<Next> returns the object's new position, which is a number
+between 1 and the number of hunks (inclusive), or returns a false value.
+
+=item C<Prev>
+
+C<Prev($N)> is almost identical to C<Next(-$N)>; it moves to the $Nth
+previous hunk.  On a 'reset' object, C<Prev()> [and C<Next(-1)>] move
+to the last hunk.
+
+The position returned by C<Prev> is relative to the I<end> of the
+hunks; -1 for the last hunk, -2 for the second-to-last, etc.
+
+=item C<Reset>
+
+    $diff->Reset();     # Reset the object's position
+    $diff->Reset($pos); # Move to the specified hunk
+    $diff->Reset(1);    # Move to the first hunk
+    $diff->Reset(-1);   # Move to the last hunk
+
+C<Reset> returns the object, so, for example, you could use
+C<< $diff->Reset()->Next(-1) >> to get the number of hunks.
+
+=item C<Copy>
+
+    $copy = $diff->Copy( $newPos, $newBase );
+
+C<Copy> returns a copy of the object.  The copy and the orignal object
+share most of their data, so making copies takes very little memory.
+The copy maintains its own position (separate from the original), which
+is the main purpose of copies.  It also maintains its own base.
+
+By default, the copy's position starts out the same as the original
+object's position.  But C<Copy> takes an optional first argument to set the
+new position, so the following three snippets are equivalent:
+
+    $copy = $diff->Copy($pos);
+
+    $copy = $diff->Copy();
+    $copy->Reset($pos);
+
+    $copy = $diff->Copy()->Reset($pos);
+
+C<Copy> takes an optional second argument to set the base for
+the copy.  If you wish to change the base of the copy but leave
+the position the same as in the original, here are two
+equivalent ways:
+
+    $copy = $diff->Copy();
+    $copy->Base( 0 );
+
+    $copy = $diff->Copy(undef,0);
+
+Here are two equivalent way to get a "reset" copy:
+
+    $copy = $diff->Copy(0);
+
+    $copy = $diff->Copy()->Reset();
+
+=item C<Diff>
+
+    $bits = $obj->Diff();
+
+C<Diff> returns a true value iff the current hunk contains items that are
+different between the two sequences.  It actually returns one of the
+follow 4 values:
+
+=over 4
+
+=item 3
+
+C<3==(1|2)>.  This hunk contains items from @seq1 and the items
+from @seq2 that should replace them.  Both sequence 1 and 2
+contain changed items so both the 1 and 2 bits are set.
+
+=item 2
+
+This hunk only contains items from @seq2 that should be inserted (not
+items from @seq1).  Only sequence 2 contains changed items so only the 2
+bit is set.
+
+=item 1
+
+This hunk only contains items from @seq1 that should be deleted (not
+items from @seq2).  Only sequence 1 contains changed items so only the 1
+bit is set.
+
+=item 0
+
+This means that the items in this hunk are the same in both sequences.
+Neither sequence 1 nor 2 contain changed items so neither the 1 nor the
+2 bits are set.
+
+=back
+
+=item C<Same>
+
+C<Same> returns a true value iff the current hunk contains items that
+are the same in both sequences.  It actually returns the list of items
+if they are the same or an emty list if they aren't.  In a scalar
+context, it returns the size of the list.
+
+=item C<Items>
+
+    $count = $diff->Items(2);
+    @items = $diff->Items($seqNum);
+
+C<Items> returns the (number of) items from the specified sequence that
+are part of the current hunk.
+
+If the current hunk contains only insertions, then
+C<< $diff->Items(1) >> will return an empty list (0 in a scalar conext).
+If the current hunk contains only deletions, then C<< $diff->Items(2) >>
+will return an empty list (0 in a scalar conext).
+
+If the hunk contains replacements, then both C<< $diff->Items(1) >> and
+C<< $diff->Items(2) >> will return different, non-empty lists.
+
+Otherwise, the hunk contains identical items and all of the following
+will return the same lists:
+
+    @items = $diff->Items(1);
+    @items = $diff->Items(2);
+    @items = $diff->Same();
+
+=item C<Range>
+
+    $count = $diff->Range( $seqNum );
+    @indices = $diff->Range( $seqNum );
+    @indices = $diff->Range( $seqNum, $base );
+
+C<Range> is like C<Items> except that it returns a list of I<indices> to
+the items rather than the items themselves.  By default, the index of
+the first item (in each sequence) is 0 but this can be changed by
+calling the C<Base> method.  So, by default, the following two snippets
+return the same lists:
+
+    @list = $diff->Items(2);
+    @list = @seq2[ $diff->Range(2) ];
+
+You can also specify the base to use as the second argument.  So the
+following two snippets I<always> return the same lists:
+
+    @list = $diff->Items(1);
+    @list = @seq1[ $diff->Range(1,0) ];
+
+=item C<Base>
+
+    $curBase = $diff->Base();
+    $oldBase = $diff->Base($newBase);
+
+C<Base> sets and/or returns the current base (usually 0 or 1) that is
+used when you request range information.  The base defaults to 0 so
+that range information is returned as array indices.  You can set the
+base to 1 if you want to report traditional line numbers instead.
+
+=item C<Min>
+
+    $min1 = $diff->Min(1);
+    $min = $diff->Min( $seqNum, $base );
+
+C<Min> returns the first value that C<Range> would return (given the
+same arguments) or returns C<undef> if C<Range> would return an empty
+list.
+
+=item C<Max>
+
+C<Max> returns the last value that C<Range> would return or C<undef>.
+
+=item C<Get>
+
+    ( $n, $x, $r ) = $diff->Get(qw( min1 max1 range1 ));
+    @values = $diff->Get(qw( 0min2 1max2 range2 same base ));
+
+C<Get> returns one or more scalar values.  You pass in a list of the
+names of the values you want returned.  Each name must match one of the
+following regexes:
+
+    /^(-?\d+)?(min|max)[12]$/i
+    /^(range[12]|same|diff|base)$/i
+
+The 1 or 2 after a name says which sequence you want the information
+for (and where allowed, it is required).  The optional number before
+"min" or "max" is the base to use.  So the following equalities hold:
+
+    $diff->Get('min1') == $diff->Min(1)
+    $diff->Get('0min2') == $diff->Min(2,0)
+
+Using C<Get> in a scalar context when you've passed in more than one
+name is a fatal error (C<die> is called).
+
+=back
+
+=head2 C<prepare>
+
+Given a reference to a list of items, C<prepare> returns a reference
+to a hash which can be used when comparing this sequence to other
+sequences with C<LCS> or C<LCS_length>.
+
+    $prep = prepare( \@seq1 );
+    for $i ( 0 .. 10_000 )
+    {
+        @lcs = LCS( $prep, $seq[$i] );
+        # do something useful with @lcs
+    }
+
+C<prepare> may be passed an optional third parameter; this is a CODE
+reference to a key generation function.  See L</KEY GENERATION
+FUNCTIONS>.
+
+    $prep = prepare( \@seq1, \&keyGen );
+    for $i ( 0 .. 10_000 )
+    {
+        @lcs = LCS( $seq[$i], $prep, \&keyGen );
+        # do something useful with @lcs
+    }
+
+Using C<prepare> provides a performance gain of about 50% when calling LCS
+many times compared with not preparing.
+
+=head2 C<diff>
+
+    @diffs     = diff( \@seq1, \@seq2 );
+    $diffs_ref = diff( \@seq1, \@seq2 );
+
+C<diff> computes the smallest set of additions and deletions necessary
+to turn the first sequence into the second, and returns a description
+of these changes.  The description is a list of I<hunks>; each hunk
+represents a contiguous section of items which should be added,
+deleted, or replaced.  (Hunks containing unchanged items are not
+included.)
+
+The return value of C<diff> is a list of hunks, or, in scalar context, a
+reference to such a list.  If there are no differences, the list will be
+empty.
+
+Here is an example.  Calling C<diff> for the following two sequences:
+
+    a b c e h j l m n p
+    b c d e f j k l m r s t
+
+would produce the following list:
+
+    (
+      [ [ '-', 0, 'a' ] ],
+
+      [ [ '+', 2, 'd' ] ],
+
+      [ [ '-', 4, 'h' ],
+        [ '+', 4, 'f' ] ],
+
+      [ [ '+', 6, 'k' ] ],
+
+      [ [ '-',  8, 'n' ],
+        [ '-',  9, 'p' ],
+        [ '+',  9, 'r' ],
+        [ '+', 10, 's' ],
+        [ '+', 11, 't' ] ],
+    )
+
+There are five hunks here.  The first hunk says that the C<a> at
+position 0 of the first sequence should be deleted (C<->).  The second
+hunk says that the C<d> at position 2 of the second sequence should
+be inserted (C<+>).  The third hunk says that the C<h> at position 4
+of the first sequence should be removed and replaced with the C<f>
+from position 4 of the second sequence.  And so on.
+
+C<diff> may be passed an optional third parameter; this is a CODE
+reference to a key generation function.  See L</KEY GENERATION
+FUNCTIONS>.
+
+Additional parameters, if any, will be passed to the key generation
+routine.
+
+=head2 C<sdiff>
+
+    @sdiffs     = sdiff( \@seq1, \@seq2 );
+    $sdiffs_ref = sdiff( \@seq1, \@seq2 );
+
+C<sdiff> computes all necessary components to show two sequences
+and their minimized differences side by side, just like the
+Unix-utility I<sdiff> does:
+
+    same             same
+    before     |     after
+    old        <     -
+    -          >     new
+
+It returns a list of array refs, each pointing to an array of
+display instructions. In scalar context it returns a reference
+to such a list. If there are no differences, the list will have one
+entry per item, each indicating that the item was unchanged.
+
+Display instructions consist of three elements: A modifier indicator
+(C<+>: Element added, C<->: Element removed, C<u>: Element unmodified,
+C<c>: Element changed) and the value of the old and new elements, to
+be displayed side-by-side.
+
+An C<sdiff> of the following two sequences:
+
+    a b c e h j l m n p
+    b c d e f j k l m r s t
+
+results in
+
+    ( [ '-', 'a', ''  ],
+      [ 'u', 'b', 'b' ],
+      [ 'u', 'c', 'c' ],
+      [ '+', '',  'd' ],
+      [ 'u', 'e', 'e' ],
+      [ 'c', 'h', 'f' ],
+      [ 'u', 'j', 'j' ],
+      [ '+', '',  'k' ],
+      [ 'u', 'l', 'l' ],
+      [ 'u', 'm', 'm' ],
+      [ 'c', 'n', 'r' ],
+      [ 'c', 'p', 's' ],
+      [ '+', '',  't' ],
+    )
+
+C<sdiff> may be passed an optional third parameter; this is a CODE
+reference to a key generation function.  See L</KEY GENERATION
+FUNCTIONS>.
+
+Additional parameters, if any, will be passed to the key generation
+routine.
+
+=head2 C<compact_diff>
+
+C<compact_diff> is much like C<sdiff> except it returns a much more
+compact description consisting of just one flat list of indices.  An
+example helps explain the format:
+
+    my @a = qw( a b c   e  h j   l m n p      );
+    my @b = qw(   b c d e f  j k l m    r s t );
+    @cdiff = compact_diff( \@a, \@b );
+    # Returns:
+    #   @a      @b       @a       @b
+    #  start   start   values   values
+    (    0,      0,   #       =
+         0,      0,   #    a  !
+         1,      0,   #  b c  =  b c
+         3,      2,   #       !  d
+         3,      3,   #    e  =  e
+         4,      4,   #    f  !  h
+         5,      5,   #    j  =  j
+         6,      6,   #       !  k
+         6,      7,   #  l m  =  l m
+         8,      9,   #  n p  !  r s t
+        10,     12,   #
+    );
+
+The 0th, 2nd, 4th, etc. entries are all indices into @seq1 (@a in the
+above example) indicating where a hunk begins.  The 1st, 3rd, 5th, etc.
+entries are all indices into @seq2 (@b in the above example) indicating
+where the same hunk begins.
+
+So each pair of indices (except the last pair) describes where a hunk
+begins (in each sequence).  Since each hunk must end at the item just
+before the item that starts the next hunk, the next pair of indices can
+be used to determine where the hunk ends.
+
+So, the first 4 entries (0..3) describe the first hunk.  Entries 0 and 1
+describe where the first hunk begins (and so are always both 0).
+Entries 2 and 3 describe where the next hunk begins, so subtracting 1
+from each tells us where the first hunk ends.  That is, the first hunk
+contains items C<$diff[0]> through C<$diff[2] - 1> of the first sequence
+and contains items C<$diff[1]> through C<$diff[3] - 1> of the second
+sequence.
+
+In other words, the first hunk consists of the following two lists of items:
+
+               #  1st pair     2nd pair
+               # of indices   of indices
+    @list1 = @a[ $cdiff[0] .. $cdiff[2]-1 ];
+    @list2 = @b[ $cdiff[1] .. $cdiff[3]-1 ];
+               # Hunk start   Hunk end
+
+Note that the hunks will always alternate between those that are part of
+the LCS (those that contain unchanged items) and those that contain
+changes.  This means that all we need to be told is whether the first
+hunk is a 'same' or 'diff' hunk and we can determine which of the other
+hunks contain 'same' items or 'diff' items.
+
+By convention, we always make the first hunk contain unchanged items.
+So the 1st, 3rd, 5th, etc. hunks (all odd-numbered hunks if you start
+counting from 1) all contain unchanged items.  And the 2nd, 4th, 6th,
+etc. hunks (all even-numbered hunks if you start counting from 1) all
+contain changed items.
+
+Since @a and @b don't begin with the same value, the first hunk in our
+example is empty (otherwise we'd violate the above convention).  Note
+that the first 4 index values in our example are all zero.  Plug these
+values into our previous code block and we get:
+
+    @hunk1a = @a[ 0 .. 0-1 ];
+    @hunk1b = @b[ 0 .. 0-1 ];
+
+And C<0..-1> returns the empty list.
+
+Move down one pair of indices (2..5) and we get the offset ranges for
+the second hunk, which contains changed items.
+
+Since C<@diff[2..5]> contains (0,0,1,0) in our example, the second hunk
+consists of these two lists of items:
+
+        @hunk2a = @a[ $cdiff[2] .. $cdiff[4]-1 ];
+        @hunk2b = @b[ $cdiff[3] .. $cdiff[5]-1 ];
+    # or
+        @hunk2a = @a[ 0 .. 1-1 ];
+        @hunk2b = @b[ 0 .. 0-1 ];
+    # or
+        @hunk2a = @a[ 0 .. 0 ];
+        @hunk2b = @b[ 0 .. -1 ];
+    # or
+        @hunk2a = ( 'a' );
+        @hunk2b = ( );
+
+That is, we would delete item 0 ('a') from @a.
+
+Since C<@diff[4..7]> contains (1,0,3,2) in our example, the third hunk
+consists of these two lists of items:
+
+        @hunk3a = @a[ $cdiff[4] .. $cdiff[6]-1 ];
+        @hunk3a = @b[ $cdiff[5] .. $cdiff[7]-1 ];
+    # or
+        @hunk3a = @a[ 1 .. 3-1 ];
+        @hunk3a = @b[ 0 .. 2-1 ];
+    # or
+        @hunk3a = @a[ 1 .. 2 ];
+        @hunk3a = @b[ 0 .. 1 ];
+    # or
+        @hunk3a = qw( b c );
+        @hunk3a = qw( b c );
+
+Note that this third hunk contains unchanged items as our convention demands.
+
+You can continue this process until you reach the last two indices,
+which will always be the number of items in each sequence.  This is
+required so that subtracting one from each will give you the indices to
+the last items in each sequence.
+
+=head2 C<traverse_sequences>
+
+C<traverse_sequences> used to be the most general facility provided by
+this module (the new OO interface is more powerful and much easier to
+use).
+
+Imagine that there are two arrows.  Arrow A points to an element of
+sequence A, and arrow B points to an element of the sequence B. 
+Initially, the arrows point to the first elements of the respective
+sequences.  C<traverse_sequences> will advance the arrows through the
+sequences one element at a time, calling an appropriate user-specified
+callback function before each advance.  It willadvance the arrows in
+such a way that if there are equal elements C<$A[$i]> and C<$B[$j]>
+which are equal and which are part of the LCS, there will be some moment
+during the execution of C<traverse_sequences> when arrow A is pointing
+to C<$A[$i]> and arrow B is pointing to C<$B[$j]>.  When this happens,
+C<traverse_sequences> will call the C<MATCH> callback function and then
+it will advance both arrows.
+
+Otherwise, one of the arrows is pointing to an element of its sequence
+that is not part of the LCS.  C<traverse_sequences> will advance that
+arrow and will call the C<DISCARD_A> or the C<DISCARD_B> callback,
+depending on which arrow it advanced.  If both arrows point to elements
+that are not part of the LCS, then C<traverse_sequences> will advance
+one of them and call the appropriate callback, but it is not specified
+which it will call.
+
+The arguments to C<traverse_sequences> are the two sequences to
+traverse, and a hash which specifies the callback functions, like this:
+
+    traverse_sequences(
+        \@seq1, \@seq2,
+        {   MATCH => $callback_1,
+            DISCARD_A => $callback_2,
+            DISCARD_B => $callback_3,
+        }
+    );
+
+Callbacks for MATCH, DISCARD_A, and DISCARD_B are invoked with at least
+the indices of the two arrows as their arguments.  They are not expected
+to return any values.  If a callback is omitted from the table, it is
+not called.
+
+Callbacks for A_FINISHED and B_FINISHED are invoked with at least the
+corresponding index in A or B.
+
+If arrow A reaches the end of its sequence, before arrow B does,
+C<traverse_sequences> will call the C<A_FINISHED> callback when it
+advances arrow B, if there is such a function; if not it will call
+C<DISCARD_B> instead.  Similarly if arrow B finishes first. 
+C<traverse_sequences> returns when both arrows are at the ends of their
+respective sequences.  It returns true on success and false on failure. 
+At present there is no way to fail.
+
+C<traverse_sequences> may be passed an optional fourth parameter; this
+is a CODE reference to a key generation function.  See L</KEY GENERATION
+FUNCTIONS>.
+
+Additional parameters, if any, will be passed to the key generation function.
+
+If you want to pass additional parameters to your callbacks, but don't
+need a custom key generation function, you can get the default by
+passing undef:
+
+    traverse_sequences(
+        \@seq1, \@seq2,
+        {   MATCH => $callback_1,
+            DISCARD_A => $callback_2,
+            DISCARD_B => $callback_3,
+        },
+        undef,     # default key-gen
+        $myArgument1,
+        $myArgument2,
+        $myArgument3,
+    );
+
+C<traverse_sequences> does not have a useful return value; you are
+expected to plug in the appropriate behavior with the callback
+functions.
+
+=head2 C<traverse_balanced>
+
+C<traverse_balanced> is an alternative to C<traverse_sequences>. It
+uses a different algorithm to iterate through the entries in the
+computed LCS. Instead of sticking to one side and showing element changes
+as insertions and deletions only, it will jump back and forth between
+the two sequences and report I<changes> occurring as deletions on one
+side followed immediatly by an insertion on the other side.
+
+In addition to the C<DISCARD_A>, C<DISCARD_B>, and C<MATCH> callbacks
+supported by C<traverse_sequences>, C<traverse_balanced> supports
+a C<CHANGE> callback indicating that one element got C<replaced> by another:
+
+    traverse_balanced(
+        \@seq1, \@seq2,
+        {   MATCH => $callback_1,
+            DISCARD_A => $callback_2,
+            DISCARD_B => $callback_3,
+            CHANGE    => $callback_4,
+        }
+    );
+
+If no C<CHANGE> callback is specified, C<traverse_balanced>
+will map C<CHANGE> events to C<DISCARD_A> and C<DISCARD_B> actions,
+therefore resulting in a similar behaviour as C<traverse_sequences>
+with different order of events.
+
+C<traverse_balanced> might be a bit slower than C<traverse_sequences>,
+noticable only while processing huge amounts of data.
+
+The C<sdiff> function of this module 
+is implemented as call to C<traverse_balanced>.
+
+C<traverse_balanced> does not have a useful return value; you are expected to
+plug in the appropriate behavior with the callback functions.
+
+=head1 KEY GENERATION FUNCTIONS
+
+Most of the functions accept an optional extra parameter.  This is a
+CODE reference to a key generating (hashing) function that should return
+a string that uniquely identifies a given element.  It should be the
+case that if two elements are to be considered equal, their keys should
+be the same (and the other way around).  If no key generation function
+is provided, the key will be the element as a string.
+
+By default, comparisons will use "eq" and elements will be turned into keys
+using the default stringizing operator '""'.
+
+Where this is important is when you're comparing something other than
+strings.  If it is the case that you have multiple different objects
+that should be considered to be equal, you should supply a key
+generation function. Otherwise, you have to make sure that your arrays
+contain unique references.
+
+For instance, consider this example:
+
+    package Person;
+
+    sub new
+    {
+        my $package = shift;
+        return bless { name => '', ssn => '', @_ }, $package;
+    }
+
+    sub clone
+    {
+        my $old = shift;
+        my $new = bless { %$old }, ref($old);
+    }
+
+    sub hash
+    {
+        return shift()->{'ssn'};
+    }
+
+    my $person1 = Person->new( name => 'Joe', ssn => '123-45-6789' );
+    my $person2 = Person->new( name => 'Mary', ssn => '123-47-0000' );
+    my $person3 = Person->new( name => 'Pete', ssn => '999-45-2222' );
+    my $person4 = Person->new( name => 'Peggy', ssn => '123-45-9999' );
+    my $person5 = Person->new( name => 'Frank', ssn => '000-45-9999' );
+
+If you did this:
+
+    my $array1 = [ $person1, $person2, $person4 ];
+    my $array2 = [ $person1, $person3, $person4, $person5 ];
+    Algorithm::Diff::diff( $array1, $array2 );
+
+everything would work out OK (each of the objects would be converted
+into a string like "Person=HASH(0x82425b0)" for comparison).
+
+But if you did this:
+
+    my $array1 = [ $person1, $person2, $person4 ];
+    my $array2 = [ $person1, $person3, $person4->clone(), $person5 ];
+    Algorithm::Diff::diff( $array1, $array2 );
+
+$person4 and $person4->clone() (which have the same name and SSN)
+would be seen as different objects. If you wanted them to be considered
+equivalent, you would have to pass in a key generation function:
+
+    my $array1 = [ $person1, $person2, $person4 ];
+    my $array2 = [ $person1, $person3, $person4->clone(), $person5 ];
+    Algorithm::Diff::diff( $array1, $array2, \&Person::hash );
+
+This would use the 'ssn' field in each Person as a comparison key, and
+so would consider $person4 and $person4->clone() as equal.
+
+You may also pass additional parameters to the key generation function
+if you wish.
+
+=head1 ERROR CHECKING
+
+If you pass these routines a non-reference and they expect a reference,
+they will die with a message.
+
+=head1 AUTHOR
+
+This version released by Tye McQueen (http://perlmonks.org/?node=tye).
+
+=head1 LICENSE
+
+Parts Copyright (c) 2000-2004 Ned Konz.  All rights reserved.
+Parts by Tye McQueen.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl.
+
+=head1 MAILING LIST
+
+Mark-Jason still maintains a mailing list.  To join a low-volume mailing
+list for announcements related to diff and Algorithm::Diff, send an
+empty mail message to mjd-perl-diff-request@plover.com.
+
+=head1 CREDITS
+
+Versions through 0.59 (and much of this documentation) were written by:
+
+Mark-Jason Dominus, mjd-perl-diff@plover.com
+
+This version borrows some documentation and routine names from
+Mark-Jason's, but Diff.pm's code was completely replaced.
+
+This code was adapted from the Smalltalk code of Mario Wolczko
+<mario@wolczko.com>, which is available at
+ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
+
+C<sdiff> and C<traverse_balanced> were written by Mike Schilli
+<m@perlmeister.com>.
+
+The algorithm is that described in
+I<A Fast Algorithm for Computing Longest Common Subsequences>,
+CACM, vol.20, no.5, pp.350-353, May 1977, with a few
+minor improvements to improve the speed.
+
+Much work was done by Ned Konz (perl@bike-nomad.com).
+
+The OO interface and some other changes are by Tye McQueen.
+
+=cut
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/lib/Algorithm/DiffOld.pm b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/lib/Algorithm/DiffOld.pm
new file mode 100644 (file)
index 0000000..511741a
--- /dev/null
@@ -0,0 +1,305 @@
+# This is a version of Algorithm::Diff that uses only a comparison function,
+# like versions <= 0.59 used to.
+# $Revision: 1.3 $
+
+package Algorithm::DiffOld;
+use strict;
+use vars qw($VERSION @EXPORT_OK @ISA @EXPORT);
+use integer;           # see below in _replaceNextLargerWith() for mod to make
+                                       # if you don't use this
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw(LCS diff traverse_sequences);
+$VERSION = 1.10;       # manually tracking Algorithm::Diff
+
+# McIlroy-Hunt diff algorithm
+# Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com>
+# by Ned Konz, perl@bike-nomad.com
+
+=head1 NAME
+
+Algorithm::DiffOld - Compute `intelligent' differences between two files / lists
+but use the old (<=0.59) interface.
+
+=head1 NOTE
+
+This has been provided as part of the Algorithm::Diff package by Ned Konz.
+This particular module is B<ONLY> for people who B<HAVE> to have the old
+interface, which uses a comparison function rather than a key generating
+function.
+
+Because each of the lines in one array have to be compared with each 
+of the lines in the other array, this does M*N comparisions. This can
+be very slow. I clocked it at taking 18 times as long as the stock
+version of Algorithm::Diff for a 4000-line file. It will get worse
+quadratically as array sizes increase.
+
+=head1 SYNOPSIS
+
+  use Algorithm::DiffOld qw(diff LCS traverse_sequences);
+
+  @lcs    = LCS( \@seq1, \@seq2, $comparison_function );
+
+  $lcsref = LCS( \@seq1, \@seq2, $comparison_function );
+
+  @diffs = diff( \@seq1, \@seq2, $comparison_function );
+  
+  traverse_sequences( \@seq1, \@seq2,
+                     { MATCH => $callback,
+                       DISCARD_A => $callback,
+                       DISCARD_B => $callback,
+                     },
+                     $comparison_function );
+
+=head1 COMPARISON FUNCTIONS
+
+Each of the main routines should be passed a comparison function. If you
+aren't passing one in, B<use Algorithm::Diff instead>.
+
+These functions should return a true value when two items should compare
+as equal.
+
+For instance,
+
+  @lcs    = LCS( \@seq1, \@seq2, sub { my ($a, $b) = @_; $a eq $b } );
+
+but if that is all you're doing with your comparison function, just use
+Algorithm::Diff and let it do this (this is its default).
+
+Or:
+
+  sub someFunkyComparisonFunction
+  {
+       my ($a, $b) = @_;
+       $a =~ m{$b};
+  }
+
+  @diffs = diff( \@lines, \@patterns, \&someFunkyComparisonFunction );
+
+which would allow you to diff an array @lines which consists of text
+lines with an array @patterns which consists of regular expressions.
+
+This is actually the reason I wrote this version -- there is no way
+to do this with a key generation function as in the stock Algorithm::Diff.
+
+=cut
+
+# Find the place at which aValue would normally be inserted into the array. If
+# that place is already occupied by aValue, do nothing, and return undef. If
+# the place does not exist (i.e., it is off the end of the array), add it to
+# the end, otherwise replace the element at that point with aValue.
+# It is assumed that the array's values are numeric.
+# This is where the bulk (75%) of the time is spent in this module, so try to
+# make it fast!
+
+sub _replaceNextLargerWith
+{
+       my ( $array, $aValue, $high ) = @_;
+       $high ||= $#$array;
+
+       # off the end?
+       if ( $high == -1  || $aValue > $array->[ -1 ] )
+       {
+               push( @$array, $aValue );
+               return $high + 1;
+       }
+
+       # binary search for insertion point...
+       my $low = 0;
+       my $index;
+       my $found;
+       while ( $low <= $high )
+       {
+               $index = ( $high + $low ) / 2;
+#              $index = int(( $high + $low ) / 2);             # without 'use integer'
+               $found = $array->[ $index ];
+
+               if ( $aValue == $found )
+               {
+                       return undef;
+               }
+               elsif ( $aValue > $found )
+               {
+                       $low = $index + 1;
+               }
+               else
+               {
+                       $high = $index - 1;
+               }
+       }
+
+       # now insertion point is in $low.
+       $array->[ $low ] = $aValue;             # overwrite next larger
+       return $low;
+}
+
+# This method computes the longest common subsequence in $a and $b.
+
+# Result is array or ref, whose contents is such that
+#      $a->[ $i ] == $b->[ $result[ $i ] ]
+# foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined.
+
+# An additional argument may be passed; this is a CODE ref to a comparison
+# routine. By default, comparisons will use "eq" .
+# Note that this routine will be called as many as M*N times, so make it fast!
+
+# Additional parameters, if any, will be passed to the key generation routine.
+
+sub _longestCommonSubsequence
+{
+       my $a = shift;  # array ref
+       my $b = shift;  # array ref
+       my $compare = shift || sub { my $a = shift; my $b = shift; $a eq $b };
+
+       my $aStart = 0;
+       my $aFinish = $#$a;
+       my $bStart = 0;
+       my $bFinish = $#$b;
+       my $matchVector = [];
+
+       # First we prune off any common elements at the beginning
+       while ( $aStart <= $aFinish
+               and $bStart <= $bFinish
+               and &$compare( $a->[ $aStart ], $b->[ $bStart ], @_ ) )
+       {
+               $matchVector->[ $aStart++ ] = $bStart++;
+       }
+
+       # now the end
+       while ( $aStart <= $aFinish
+               and $bStart <= $bFinish
+               and &$compare( $a->[ $aFinish ], $b->[ $bFinish ], @_ ) )
+       {
+               $matchVector->[ $aFinish-- ] = $bFinish--;
+       }
+
+       my $thresh = [];
+       my $links = [];
+
+       my ( $i, $ai, $j, $k );
+       for ( $i = $aStart; $i <= $aFinish; $i++ )
+       {
+               $k = 0;
+               # look for each element of @b between $bStart and $bFinish
+               # that matches $a->[ $i ], in reverse order
+               for ($j = $bFinish; $j >= $bStart; $j--)
+               {
+                       next if ! &$compare( $a->[$i], $b->[$j], @_ );
+                       # optimization: most of the time this will be true
+                       if ( $k
+                               and $thresh->[ $k ] > $j
+                               and $thresh->[ $k - 1 ] < $j )
+                       {
+                               $thresh->[ $k ] = $j;
+                       }
+                       else
+                       {
+                               $k = _replaceNextLargerWith( $thresh, $j, $k );
+                       }
+
+                       # oddly, it's faster to always test this (CPU cache?).
+                       if ( defined( $k ) )
+                       {
+                               $links->[ $k ] = 
+                                       [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];
+                       }
+               }
+       }
+
+       if ( @$thresh )
+       {
+               for ( my $link = $links->[ $#$thresh ]; $link; $link = $link->[ 0 ] )
+               {
+                       $matchVector->[ $link->[ 1 ] ] = $link->[ 2 ];
+               }
+       }
+
+       return wantarray ? @$matchVector : $matchVector;
+}
+
+sub traverse_sequences
+{
+       my $a = shift;  # array ref
+       my $b = shift;  # array ref
+       my $callbacks = shift || { };
+       my $compare = shift;
+       my $matchCallback = $callbacks->{'MATCH'} || sub { };
+       my $discardACallback = $callbacks->{'DISCARD_A'} || sub { };
+       my $finishedACallback = $callbacks->{'A_FINISHED'};
+       my $discardBCallback = $callbacks->{'DISCARD_B'} || sub { };
+       my $finishedBCallback = $callbacks->{'B_FINISHED'};
+       my $matchVector = _longestCommonSubsequence( $a, $b, $compare, @_ );
+       # Process all the lines in match vector
+       my $lastA = $#$a;
+       my $lastB = $#$b;
+       my $bi = 0;
+       my $ai;
+       for ( $ai = 0; $ai <= $#$matchVector; $ai++ )
+       {
+               my $bLine = $matchVector->[ $ai ];
+               if ( defined( $bLine ) )        # matched
+               {
+                       &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;
+                       &$matchCallback( $ai, $bi++, @_ );
+               }
+               else
+               {
+                       &$discardACallback( $ai, $bi, @_ );
+               }
+       }
+       # the last entry (if any) processed was a match.
+
+       if ( defined( $finishedBCallback ) && $ai <= $lastA )
+       {
+               &$finishedBCallback( $bi, @_ );
+       }
+       else
+       {
+               &$discardACallback( $ai++, $bi, @_ ) while ( $ai <= $lastA );
+       }
+
+       if ( defined( $finishedACallback ) && $bi <= $lastB )
+       {
+               &$finishedACallback( $ai, @_ );
+       }
+       else
+       {
+               &$discardBCallback( $ai, $bi++, @_ ) while ( $bi <= $lastB );
+       }
+       return 1;
+}
+
+sub LCS
+{
+       my $a = shift;  # array ref
+       my $matchVector = _longestCommonSubsequence( $a, @_ );
+       my @retval;
+       my $i;
+       for ( $i = 0; $i <= $#$matchVector; $i++ )
+       {
+               if ( defined( $matchVector->[ $i ] ) )
+               {
+                       push( @retval, $a->[ $i ] );
+               }
+       }
+       return wantarray ? @retval : \@retval;
+}
+
+sub diff
+{
+       my $a = shift;  # array ref
+       my $b = shift;  # array ref
+       my $retval = [];
+       my $hunk = [];
+       my $discard = sub { push( @$hunk, [ '-', $_[ 0 ], $a->[ $_[ 0 ] ] ] ) };
+       my $add = sub { push( @$hunk, [ '+', $_[ 1 ], $b->[ $_[ 1 ] ] ] ) };
+       my $match = sub { push( @$retval, $hunk ) if scalar(@$hunk); $hunk = [] };
+       traverse_sequences( $a, $b,
+               { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add },
+               @_ );
+       &$match();
+       return wantarray ? @$retval : $retval;
+}
+
+1;
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/t/base.t b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/t/base.t
new file mode 100644 (file)
index 0000000..7ad823a
--- /dev/null
@@ -0,0 +1,402 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl base.t'
+use strict;
+$^W++;
+use lib qw(blib lib);
+use Algorithm::Diff qw(diff LCS traverse_sequences traverse_balanced sdiff);
+use Data::Dumper;
+use Test;
+
+BEGIN
+{
+       $|++;
+       plan tests => 35;
+       $SIG{__DIE__} = sub # breakpoint on die
+       {
+               $DB::single = 1;
+               $DB::single = 1;        # avoid complaint
+               die @_;
+       }
+}
+
+my @a = qw(a b c e h j l m n p);
+my @b = qw(b c d e f j k l m r s t);
+my @correctResult = qw(b c e j l m);
+my $correctResult = join(' ', @correctResult);
+my $skippedA = 'a h n p';
+my $skippedB = 'd f k r s t';
+
+# From the Algorithm::Diff manpage:
+my $correctDiffResult = [
+       [ [ '-', 0, 'a' ] ],
+
+       [ [ '+', 2, 'd' ] ],
+
+       [ [ '-', 4, 'h' ], [ '+', 4, 'f' ] ],
+
+       [ [ '+', 6, 'k' ] ],
+
+       [
+               [ '-', 8,  'n' ], 
+               [ '+', 9,  'r' ], 
+               [ '-', 9,  'p' ],
+               [ '+', 10, 's' ],
+               [ '+', 11, 't' ],
+       ]
+];
+
+# Result of LCS must be as long as @a
+my @result = Algorithm::Diff::_longestCommonSubsequence( \@a, \@b );
+ok( scalar(grep { defined } @result),
+       scalar(@correctResult),
+       "length of _longestCommonSubsequence" );
+
+# result has b[] line#s keyed by a[] line#
+# print "result =", join(" ", map { defined($_) ? $_ : 'undef' } @result), "\n";
+
+my @aresult = map { defined( $result[$_] ) ? $a[$_] : () } 0 .. $#result;
+my @bresult =
+  map { defined( $result[$_] ) ? $b[ $result[$_] ] : () } 0 .. $#result;
+
+ok( "@aresult", $correctResult, "A results" );
+ok( "@bresult", $correctResult, "B results" );
+
+my ( @matchedA, @matchedB, @discardsA, @discardsB, $finishedA, $finishedB );
+
+sub match
+{
+       my ( $a, $b ) = @_;
+       push ( @matchedA, $a[$a] );
+       push ( @matchedB, $b[$b] );
+}
+
+sub discard_b
+{
+       my ( $a, $b ) = @_;
+       push ( @discardsB, $b[$b] );
+}
+
+sub discard_a
+{
+       my ( $a, $b ) = @_;
+       push ( @discardsA, $a[$a] );
+}
+
+sub finished_a
+{
+       my ( $a, $b ) = @_;
+       $finishedA = $a;
+}
+
+sub finished_b
+{
+       my ( $a, $b ) = @_;
+       $finishedB = $b;
+}
+
+traverse_sequences(
+       \@a,
+       \@b,
+       {
+               MATCH     => \&match,
+               DISCARD_A => \&discard_a,
+               DISCARD_B => \&discard_b
+       }
+);
+
+ok( "@matchedA", $correctResult);
+ok( "@matchedB", $correctResult);
+ok( "@discardsA", $skippedA);
+ok( "@discardsB", $skippedB);
+
+@matchedA = @matchedB = @discardsA = @discardsB = ();
+$finishedA = $finishedB = undef;
+
+traverse_sequences(
+       \@a,
+       \@b,
+       {
+               MATCH      => \&match,
+               DISCARD_A  => \&discard_a,
+               DISCARD_B  => \&discard_b,
+               A_FINISHED => \&finished_a,
+               B_FINISHED => \&finished_b,
+       }
+);
+
+ok( "@matchedA", $correctResult);
+ok( "@matchedB", $correctResult);
+ok( "@discardsA", $skippedA);
+ok( "@discardsB", $skippedB);
+ok( $finishedA, 9, "index of finishedA" );
+ok( $finishedB, undef, "index of finishedB" );
+
+my @lcs = LCS( \@a, \@b );
+ok( "@lcs", $correctResult );
+
+# Compare the diff output with the one from the Algorithm::Diff manpage.
+my $diff = diff( \@a, \@b );
+$Data::Dumper::Indent = 0;
+my $cds = Dumper($correctDiffResult);
+my $dds = Dumper($diff);
+ok( $dds, $cds );
+
+##################################################
+# <Mike Schilli> m@perlmeister.com 03/23/2002: 
+# Tests for sdiff-interface
+#################################################
+
+@a = qw(abc def yyy xxx ghi jkl);
+@b = qw(abc dxf xxx ghi jkl);
+$correctDiffResult = [ ['u', 'abc', 'abc'],
+                       ['c', 'def', 'dxf'],
+                       ['-', 'yyy', ''],
+                       ['u', 'xxx', 'xxx'],
+                       ['u', 'ghi', 'ghi'],
+                       ['u', 'jkl', 'jkl'] ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+
+#################################################
+@a = qw(a b c e h j l m n p);
+@b = qw(b c d e f j k l m r s t);
+$correctDiffResult = [ ['-', 'a', '' ],
+                       ['u', 'b', 'b'],
+                       ['u', 'c', 'c'],
+                       ['+', '',  'd'],
+                       ['u', 'e', 'e'],
+                       ['c', 'h', 'f'],
+                       ['u', 'j', 'j'],
+                       ['+', '',  'k'],
+                       ['u', 'l', 'l'],
+                       ['u', 'm', 'm'],
+                       ['c', 'n', 'r'],
+                       ['c', 'p', 's'],
+                       ['+', '',  't'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a b c d e);
+@b = qw(a e);
+$correctDiffResult = [ ['u', 'a', 'a' ],
+                       ['-', 'b', ''],
+                       ['-', 'c', ''],
+                       ['-', 'd', ''],
+                       ['u', 'e', 'e'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a e);
+@b = qw(a b c d e);
+$correctDiffResult = [ ['u', 'a', 'a' ],
+                       ['+', '', 'b'],
+                       ['+', '', 'c'],
+                       ['+', '', 'd'],
+                       ['u', 'e', 'e'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(v x a e);
+@b = qw(w y a b c d e);
+$correctDiffResult = [ 
+                       ['c', 'v', 'w' ],
+                       ['c', 'x', 'y' ],
+                       ['u', 'a', 'a' ],
+                       ['+', '', 'b'],
+                       ['+', '', 'c'],
+                       ['+', '', 'd'],
+                       ['u', 'e', 'e'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(x a e);
+@b = qw(a b c d e);
+$correctDiffResult = [ 
+                       ['-', 'x', '' ],
+                       ['u', 'a', 'a' ],
+                       ['+', '', 'b'],
+                       ['+', '', 'c'],
+                       ['+', '', 'd'],
+                       ['u', 'e', 'e'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a e);
+@b = qw(x a b c d e);
+$correctDiffResult = [ 
+                       ['+', '', 'x' ],
+                       ['u', 'a', 'a' ],
+                       ['+', '', 'b'],
+                       ['+', '', 'c'],
+                       ['+', '', 'd'],
+                       ['u', 'e', 'e'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a e v);
+@b = qw(x a b c d e w x);
+$correctDiffResult = [ 
+                       ['+', '', 'x' ],
+                       ['u', 'a', 'a' ],
+                       ['+', '', 'b'],
+                       ['+', '', 'c'],
+                       ['+', '', 'd'],
+                       ['u', 'e', 'e'],
+                       ['c', 'v', 'w'],
+                       ['+', '',  'x'],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw();
+@b = qw(a b c);
+$correctDiffResult = [ 
+                       ['+', '', 'a' ],
+                       ['+', '', 'b' ],
+                       ['+', '', 'c' ],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a b c);
+@b = qw();
+$correctDiffResult = [ 
+                       ['-', 'a', '' ],
+                       ['-', 'b', '' ],
+                       ['-', 'c', '' ],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a b c);
+@b = qw(1);
+$correctDiffResult = [ 
+                       ['c', 'a', '1' ],
+                       ['-', 'b', '' ],
+                       ['-', 'c', '' ],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a b c);
+@b = qw(c);
+$correctDiffResult = [ 
+                       ['-', 'a', '' ],
+                       ['-', 'b', '' ],
+                       ['u', 'c', 'c' ],
+                     ];
+@result = sdiff(\@a, \@b);
+ok(Dumper(\@result), Dumper($correctDiffResult));
+
+#################################################
+@a = qw(a b c);
+@b = qw(a x c);
+my $r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "M 0 0C 1 1M 2 2");
+
+#################################################
+# No CHANGE callback => use discard_a/b instead
+@a = qw(a b c);
+@b = qw(a x c);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                   } );
+ok($r, "M 0 0DA 1 1DB 2 1M 2 2");
+
+#################################################
+@a = qw(a x y c);
+@b = qw(a v w c);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "M 0 0C 1 1C 2 2M 3 3");
+
+#################################################
+@a = qw(x y c);
+@b = qw(v w c);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "C 0 0C 1 1M 2 2");
+
+#################################################
+@a = qw(a x y z);
+@b = qw(b v w);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "C 0 0C 1 1C 2 2DA 3 3");
+
+#################################################
+@a = qw(a z);
+@b = qw(a);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "M 0 0DA 1 1");
+
+#################################################
+@a = qw(z a);
+@b = qw(a);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "DA 0 0M 1 0");
+
+#################################################
+@a = qw(a b c);
+@b = qw(x y z);
+$r = "";
+traverse_balanced( \@a, \@b, 
+                   { MATCH     => sub { $r .= "M @_";},
+                     DISCARD_A => sub { $r .= "DA @_";},
+                     DISCARD_B => sub { $r .= "DB @_";},
+                     CHANGE    => sub { $r .= "C @_";},
+                   } );
+ok($r, "C 0 0C 1 1C 2 2");
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/t/oo.t b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl-1.19.02/t/oo.t
new file mode 100644 (file)
index 0000000..a4cf26a
--- /dev/null
@@ -0,0 +1,212 @@
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl oo.t'
+use strict;
+BEGIN { $^W++; }
+use lib qw( blib lib );
+use Algorithm::Diff qw( compact_diff );
+use Data::Dumper;
+use Test qw( plan ok $ntest );
+
+BEGIN
+{
+    $|++;
+    plan( tests => 969 );
+    $SIG{__DIE__} = sub # breakpoint on die
+    {
+        $DB::single = 1
+            if  ! $^S;
+        die @_;
+    };
+    $SIG{__WARN__} = sub # breakpoint on warn
+    {
+        $DB::single = 1;
+        warn @_;
+    };
+}
+
+sub Ok($$) { @_= reverse @_; goto &ok }
+
+my( $first, $a, $b, $hunks );
+for my $pair (
+    [ "a b c   e  h j   l m n p",
+      "  b c d e f  j k l m    r s t", 9 ],
+    [ "", "", 0 ],
+    [ "a b c", "", 1 ],
+    [ "", "a b c d", 1 ],
+    [ "a b", "x y z", 1 ],
+    [ "    c  e   h j   l m n p r",
+      "a b c d f g  j k l m      s t", 7 ],
+    [ "a b c d",
+      "a b c d", 1 ],
+    [ "a     d",
+      "a b c d", 3 ],
+    [ "a b c d",
+      "a     d", 3 ],
+    [ "a b c d",
+      "  b c  ", 3 ],
+    [ "  b c  ",
+      "a b c d", 3 ],
+) {
+    $first= $ntest;
+    ( $a, $b, $hunks )= @$pair;
+    my @a = split ' ', $a;
+    my @b = split ' ', $b;
+
+    my $d = Algorithm::Diff->new( \@a, \@b );
+
+    if(  @ARGV  ) {
+        print "1: $a$/2: $b$/";
+        while( $d->Next() ) {
+            printf "%10s %s %s$/",
+                join(' ',$d->Items(1)),
+                $d->Same() ? '=' : '|',
+                join(' ',$d->Items(2));
+        }
+    }
+
+    Ok( 0, $d->Base() );
+    Ok( 0, $d->Base(undef) );
+    Ok( 0, $d->Base(1) );
+    Ok( 1, $d->Base(undef) );
+    Ok( 1, $d->Base(0) );
+
+    ok( ! eval { $d->Diff(); 1 } );
+    ok( $@, qr/\breset\b/i );
+    ok( ! eval { $d->Same(); 1 } );
+    ok( $@, qr/\breset\b/i );
+    ok( ! eval { $d->Items(1); 1 } );
+    ok( $@, qr/\breset\b/i );
+    ok( ! eval { $d->Range(2); 1 } );
+    ok( $@, qr/\breset\b/i );
+    ok( ! eval { $d->Min(1); 1 } );
+    ok( $@, qr/\breset\b/i );
+    ok( ! eval { $d->Max(2); 1 } );
+    ok( $@, qr/\breset\b/i );
+    ok( ! eval { $d->Get('Min1'); 1 } );
+    ok( $@, qr/\breset\b/i );
+
+    ok( ! $d->Next(0) );
+    ok( ! eval { $d->Same(); 1 } );
+    ok( $@, qr/\breset\b/i );
+    Ok( 1, $d->Next() )         if  0 < $hunks;
+    Ok( 2, $d->Next(undef) )    if  1 < $hunks;
+    Ok( 3, $d->Next(1) )        if  2 < $hunks;
+    Ok( 2, $d->Next(-1) )       if  1 < $hunks;
+    ok( ! $d->Next(-2) );
+    ok( ! eval { $d->Same(); 1 } );
+    ok( $@, qr/\breset\b/i );
+
+    ok( ! $d->Prev(0) );
+    ok( ! eval { $d->Same(); 1 } );
+    ok( $@, qr/\breset\b/i );
+    Ok( -1, $d->Prev() )        if  0 < $hunks;
+    Ok( -2, $d->Prev(undef) )   if  1 < $hunks;
+    Ok( -3, $d->Prev(1) )       if  2 < $hunks;
+    Ok( -2, $d->Prev(-1) )      if  1 < $hunks;
+    ok( ! $d->Prev(-2) );
+
+    Ok( 1, $d->Next() )         if  0 < $hunks;
+    ok( ! $d->Prev() );
+    Ok( 1, $d->Next() )         if  0 < $hunks;
+    ok( ! $d->Prev(2) );
+    Ok( -1, $d->Prev() )        if  0 < $hunks;
+    ok( ! $d->Next() );
+    Ok( -1, $d->Prev() )        if  0 < $hunks;
+    ok( ! $d->Next(5) );
+
+    Ok( 1, $d->Next() )         if  0 < $hunks;
+    Ok( $d, $d->Reset() );
+    ok( ! $d->Prev(0) );
+    Ok( 3, $d->Reset(3)->Next(0) )  if  2 < $hunks;
+    Ok( -3, $d->Reset(-2)->Prev() ) if  2 < $hunks;
+    Ok( $hunks || !1, $d->Reset(0)->Next(-1) );
+
+    my $c = $d->Copy();
+    ok( $c->Base(), $d->Base() );
+    ok( $c->Next(0), $d->Next(0) );
+    ok( $d->Copy(-4)->Next(0),
+        $d->Copy()->Reset(-4)->Next(0) );
+
+    $c = $d->Copy( undef, 1 );
+    Ok( 1, $c->Base() );
+    ok( $c->Next(0), $d->Next(0) );
+
+    $d->Reset();
+    my( @A, @B );
+    while( $d->Next() ) {
+        if( $d->Same() ) {
+            Ok( 0, $d->Diff() );
+            ok( $d->Same(), $d->Range(2) );
+            ok( $d->Items(2), $d->Range(1) );
+            ok( "@{[$d->Same()]}",
+                "@{[$d->Items(1)]}" );
+            ok( "@{[$d->Items(1)]}",
+                "@{[$d->Items(2)]}" );
+            ok( "@{[$d->Items(2)]}",
+                "@a[$d->Range(1)]" );
+            ok( "@a[$d->Range(1,0)]",
+                "@b[$d->Range(2)]" );
+            push @A, $d->Same();
+            push @B, @b[$d->Range(2)];
+        } else {
+            Ok( 0, $d->Same() );
+            ok( $d->Diff() & 1, 1*!!$d->Range(1) );
+            ok( $d->Diff() & 2, 2*!!$d->Range(2) );
+            ok( "@{[$d->Items(1)]}",
+                "@a[$d->Range(1)]" );
+            ok( "@{[$d->Items(2)]}",
+                "@b[$d->Range(2,0)]" );
+            push @A, @a[$d->Range(1)];
+            push @B, $d->Items(2);
+        }
+    }
+    ok( "@A", "@a" );
+    ok( "@B", "@b" );
+
+    next   if  ! $hunks;
+
+    Ok( 1, $d->Next() );
+    { local $^W= 0;
+    ok( ! eval { $d->Items(); 1 } ); }
+    ok( ! eval { $d->Items(0); 1 } );
+    { local $^W= 0;
+    ok( ! eval { $d->Range(); 1 } ); }
+    ok( ! eval { $d->Range(3); 1 } );
+    { local $^W= 0;
+    ok( ! eval { $d->Min(); 1 } ); }
+    ok( ! eval { $d->Min(-1); 1 } );
+    { local $^W= 0;
+    ok( ! eval { $d->Max(); 1 } ); }
+    ok( ! eval { $d->Max(9); 1 } );
+
+    $d->Reset(-1);
+    $c= $d->Copy(undef,1);
+    ok( "@a[$d->Range(1)]",
+        "@{[(0,@a)[$c->Range(1)]]}" );
+    ok( "@b[$c->Range(2,0)]",
+        "@{[(0,@b)[$d->Range(2,1)]]}" );
+    ok( "@a[$d->Get('min1')..$d->Get('0Max1')]",
+        "@{[(0,@a)[$d->Get('1MIN1')..$c->Get('MAX1')]]}" );
+
+    ok( "@{[$c->Min(1),$c->Max(2,0)]}",
+        "@{[$c->Get('Min1','0Max2')]}" );
+    ok( ! eval { scalar $c->Get('Min1','0Max2'); 1 } );
+    ok( "@{[0+$d->Same(),$d->Diff(),$d->Base()]}",
+        "@{[$d->Get(qq<same Diff BASE>)]}" );
+    ok( "@{[0+$d->Range(1),0+$d->Range(2)]}",
+        "@{[$d->Get(qq<Range1 rAnGe2>)]}" );
+    { local $^W= 0;
+    ok( ! eval { $c->Get('range'); 1 } );
+    ok( ! eval { $c->Get('min'); 1 } );
+    ok( ! eval { $c->Get('max'); 1 } ); }
+
+} continue {
+    if(  @ARGV  ) {
+        my $tests= $ntest - $first;
+        print "$hunks hunks, $tests tests.$/";
+    }
+}
+
+# $d = Algorithm::Diff->new( \@a, \@b, {KeyGen=>sub...} );
+
+# @cdiffs = compact_diff( \@seq1, \@seq2 );
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.diff.gz b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.diff.gz
new file mode 100644 (file)
index 0000000..9c5bd82
Binary files /dev/null and b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.diff.gz differ
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.dsc b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1.dsc
new file mode 100644 (file)
index 0000000..fb551ed
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.0
+Source: libalgorithm-diff-perl
+Binary: libalgorithm-diff-perl
+Architecture: all
+Version: 1.19.02-1
+Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>
+Uploaders: gregor herrmann <gregor+debian@comodo.priv.at>
+Homepage: http://search.cpan.org/dist/Algorithm-Diff/
+Standards-Version: 3.7.3
+Vcs-Browser: http://svn.debian.org/wsvn/pkg-perl/trunk/libalgorithm-diff-perl/
+Vcs-Svn: svn://svn.debian.org/pkg-perl/trunk/libalgorithm-diff-perl/
+Build-Depends: debhelper (>= 5)
+Build-Depends-Indep: perl (>= 5.6.0-16)
+Files: 
+ ff3e17ae485f8adfb8857b183991fbce 33529 libalgorithm-diff-perl_1.19.02.orig.tar.gz
+ dcef32c267f1f8955ae168b1a2256b3e 3250 libalgorithm-diff-perl_1.19.02-1.diff.gz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQFH1QQqHqjlqpcl9jsRAk4zAJ9N9ZqnSEkrkb1YxRPLtL6o/LaNpwCgts0y
+17YZq6b5k5dEIIqMy6E81Zk=
+=6+cJ
+-----END PGP SIGNATURE-----
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.diff.gz b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.diff.gz
new file mode 100644 (file)
index 0000000..47143af
Binary files /dev/null and b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.diff.gz differ
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.dsc b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1.dsc
new file mode 100644 (file)
index 0000000..d9c5867
--- /dev/null
@@ -0,0 +1,13 @@
+Format: 1.0
+Source: libalgorithm-diff-perl
+Version: 1.19.02-1maemo1
+Binary: libalgorithm-diff-perl
+Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>
+Architecture: all
+Standards-Version: 3.7.3
+Build-Depends: debhelper (>= 5)
+Build-Depends-Indep: perl (>= 5.6.0-16)
+Uploaders: gregor herrmann <gregor+debian@comodo.priv.at>
+Files: 
+ ff3e17ae485f8adfb8857b183991fbce 33529 libalgorithm-diff-perl_1.19.02.orig.tar.gz
+ 161cb9a9e0c9f31cb67509ed14f90a0c 3320 libalgorithm-diff-perl_1.19.02-1maemo1.diff.gz
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1_armel.changes b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02-1maemo1_armel.changes
new file mode 100644 (file)
index 0000000..17e59ad
--- /dev/null
@@ -0,0 +1,20 @@
+Format: 1.7
+Date: Wed, 14 Apr 2010 07:09:51 +0100
+Source: libalgorithm-diff-perl
+Binary: libalgorithm-diff-perl
+Architecture: source all
+Version: 1.19.02-1maemo1
+Distribution: fremantle
+Urgency: low
+Maintainer: Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>
+Changed-By: Nito Martinez <Nito@Qindel.ES>
+Description: 
+ libalgorithm-diff-perl - a perl library for finding Longest Common Sequences in text
+Changes: 
+ libalgorithm-diff-perl (1.19.02-1maemo1) fremantle; urgency=low
+ .
+   * New Maemo packaging
+Files: 
+ ee8443a24044661783215f6b4264b6a3 526 perl optional libalgorithm-diff-perl_1.19.02-1maemo1.dsc
+ 161cb9a9e0c9f31cb67509ed14f90a0c 3320 perl optional libalgorithm-diff-perl_1.19.02-1maemo1.diff.gz
+ 117881f1f9020a0ccff71382f64527cf 51688 perl optional libalgorithm-diff-perl_1.19.02-1maemo1_all.deb
diff --git a/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02.orig.tar.gz b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02.orig.tar.gz
new file mode 100644 (file)
index 0000000..1627514
Binary files /dev/null and b/deb-src/libalgorithm-diff-perl/libalgorithm-diff-perl_1.19.02.orig.tar.gz differ
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Call/Call.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/Call/Call.pm
new file mode 100644 (file)
index 0000000..6bbf79b
--- /dev/null
@@ -0,0 +1,498 @@
+
+# Call.pm
+#
+# Copyright (c) 1995-2001 Paul Marquess. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+package Filter::Util::Call ;
+
+require 5.002 ;
+require DynaLoader;
+require Exporter;
+use Carp ;
+use strict;
+use warnings;
+use vars qw($VERSION @ISA @EXPORT) ;
+
+@ISA = qw(Exporter DynaLoader);
+@EXPORT = qw( filter_add filter_del filter_read filter_read_exact) ;
+$VERSION = "1.07" ;
+
+sub filter_read_exact($)
+{
+    my ($size)   = @_ ;
+    my ($left)   = $size ;
+    my ($status) ;
+
+    croak ("filter_read_exact: size parameter must be > 0")
+       unless $size > 0 ;
+
+    # try to read a block which is exactly $size bytes long
+    while ($left and ($status = filter_read($left)) > 0) {
+        $left = $size - length $_ ;
+    }
+
+    # EOF with pending data is a special case
+    return 1 if $status == 0 and length $_ ;
+
+    return $status ;
+}
+
+sub filter_add($)
+{
+    my($obj) = @_ ;
+
+    # Did we get a code reference?
+    my $coderef = (ref $obj eq 'CODE') ;
+
+    # If the parameter isn't already a reference, make it one.
+    $obj = \$obj unless ref $obj ;
+
+    $obj = bless ($obj, (caller)[0]) unless $coderef ;
+
+    # finish off the installation of the filter in C.
+    Filter::Util::Call::real_import($obj, (caller)[0], $coderef) ;
+}
+
+bootstrap Filter::Util::Call ;
+
+1;
+__END__
+
+=head1 NAME
+
+Filter::Util::Call - Perl Source Filter Utility Module
+
+=head1 SYNOPSIS
+
+    use Filter::Util::Call ;
+
+=head1 DESCRIPTION
+
+This module provides you with the framework to write I<Source Filters>
+in Perl. 
+
+An alternate interface to Filter::Util::Call is now available. See
+L<Filter::Simple> for more details.
+
+A I<Perl Source Filter> is implemented as a Perl module. The structure
+of the module can take one of two broadly similar formats. To
+distinguish between them, the first will be referred to as I<method
+filter> and the second as I<closure filter>.
+
+Here is a skeleton for the I<method filter>:
+
+    package MyFilter ;
+
+    use Filter::Util::Call ;
+
+    sub import
+    {
+        my($type, @arguments) = @_ ;
+        filter_add([]) ;
+    }
+
+    sub filter
+    {
+        my($self) = @_ ;
+        my($status) ;
+
+        $status = filter_read() ;
+        $status ;
+    }
+
+    1 ;
+
+and this is the equivalent skeleton for the I<closure filter>:
+
+    package MyFilter ;
+
+    use Filter::Util::Call ;
+
+    sub import
+    {
+        my($type, @arguments) = @_ ;
+
+        filter_add(
+            sub 
+            {
+                my($status) ;
+                $status = filter_read() ;
+                $status ;
+            } )
+    }
+
+    1 ;
+
+To make use of either of the two filter modules above, place the line
+below in a Perl source file.
+
+    use MyFilter; 
+
+In fact, the skeleton modules shown above are fully functional I<Source
+Filters>, albeit fairly useless ones. All they does is filter the
+source stream without modifying it at all.
+
+As you can see both modules have a broadly similar structure. They both
+make use of the C<Filter::Util::Call> module and both have an C<import>
+method. The difference between them is that the I<method filter>
+requires a I<filter> method, whereas the I<closure filter> gets the
+equivalent of a I<filter> method with the anonymous sub passed to
+I<filter_add>.
+
+To make proper use of the I<closure filter> shown above you need to
+have a good understanding of the concept of a I<closure>. See
+L<perlref> for more details on the mechanics of I<closures>.
+
+=head2 B<use Filter::Util::Call>
+
+The following functions are exported by C<Filter::Util::Call>:
+
+    filter_add()
+    filter_read()
+    filter_read_exact()
+    filter_del()
+
+=head2 B<import()>
+
+The C<import> method is used to create an instance of the filter. It is
+called indirectly by Perl when it encounters the C<use MyFilter> line
+in a source file (See L<perlfunc/import> for more details on
+C<import>).
+
+It will always have at least one parameter automatically passed by Perl
+- this corresponds to the name of the package. In the example above it
+will be C<"MyFilter">.
+
+Apart from the first parameter, import can accept an optional list of
+parameters. These can be used to pass parameters to the filter. For
+example:
+
+    use MyFilter qw(a b c) ;
+
+will result in the C<@_> array having the following values:
+
+    @_ [0] => "MyFilter"
+    @_ [1] => "a"
+    @_ [2] => "b"
+    @_ [3] => "c"
+
+Before terminating, the C<import> function must explicitly install the
+filter by calling C<filter_add>.
+
+B<filter_add()>
+
+The function, C<filter_add>, actually installs the filter. It takes one
+parameter which should be a reference. The kind of reference used will
+dictate which of the two filter types will be used.
+
+If a CODE reference is used then a I<closure filter> will be assumed.
+
+If a CODE reference is not used, a I<method filter> will be assumed.
+In a I<method filter>, the reference can be used to store context
+information. The reference will be I<blessed> into the package by
+C<filter_add>.
+
+See the filters at the end of this documents for examples of using
+context information using both I<method filters> and I<closure
+filters>.
+
+=head2 B<filter() and anonymous sub>
+
+Both the C<filter> method used with a I<method filter> and the
+anonymous sub used with a I<closure filter> is where the main
+processing for the filter is done.
+
+The big difference between the two types of filter is that the I<method
+filter> uses the object passed to the method to store any context data,
+whereas the I<closure filter> uses the lexical variables that are
+maintained by the closure.
+
+Note that the single parameter passed to the I<method filter>,
+C<$self>, is the same reference that was passed to C<filter_add>
+blessed into the filter's package. See the example filters later on for
+details of using C<$self>.
+
+Here is a list of the common features of the anonymous sub and the
+C<filter()> method.
+
+=over 5
+
+=item B<$_>
+
+Although C<$_> doesn't actually appear explicitly in the sample filters
+above, it is implicitly used in a number of places.
+
+Firstly, when either C<filter> or the anonymous sub are called, a local
+copy of C<$_> will automatically be created. It will always contain the
+empty string at this point.
+
+Next, both C<filter_read> and C<filter_read_exact> will append any
+source data that is read to the end of C<$_>.
+
+Finally, when C<filter> or the anonymous sub are finished processing,
+they are expected to return the filtered source using C<$_>.
+
+This implicit use of C<$_> greatly simplifies the filter.
+
+=item B<$status>
+
+The status value that is returned by the user's C<filter> method or
+anonymous sub and the C<filter_read> and C<read_exact> functions take
+the same set of values, namely:
+
+    < 0  Error
+    = 0  EOF
+    > 0  OK
+
+=item B<filter_read> and B<filter_read_exact>
+
+These functions are used by the filter to obtain either a line or block
+from the next filter in the chain or the actual source file if there
+aren't any other filters.
+
+The function C<filter_read> takes two forms:
+
+    $status = filter_read() ;
+    $status = filter_read($size) ;
+
+The first form is used to request a I<line>, the second requests a
+I<block>.
+
+In line mode, C<filter_read> will append the next source line to the
+end of the C<$_> scalar.
+
+In block mode, C<filter_read> will append a block of data which is <=
+C<$size> to the end of the C<$_> scalar. It is important to emphasise
+the that C<filter_read> will not necessarily read a block which is
+I<precisely> C<$size> bytes.
+
+If you need to be able to read a block which has an exact size, you can
+use the function C<filter_read_exact>. It works identically to
+C<filter_read> in block mode, except it will try to read a block which
+is exactly C<$size> bytes in length. The only circumstances when it
+will not return a block which is C<$size> bytes long is on EOF or
+error.
+
+It is I<very> important to check the value of C<$status> after I<every>
+call to C<filter_read> or C<filter_read_exact>.
+
+=item B<filter_del>
+
+The function, C<filter_del>, is used to disable the current filter. It
+does not affect the running of the filter. All it does is tell Perl not
+to call filter any more.
+
+See L<Example 4: Using filter_del> for details.
+
+=back
+
+=head1 EXAMPLES
+
+Here are a few examples which illustrate the key concepts - as such
+most of them are of little practical use.
+
+The C<examples> sub-directory has copies of all these filters
+implemented both as I<method filters> and as I<closure filters>.
+
+=head2 Example 1: A simple filter.
+
+Below is a I<method filter> which is hard-wired to replace all
+occurrences of the string C<"Joe"> to C<"Jim">. Not particularly
+Useful, but it is the first example and I wanted to keep it simple.
+
+    package Joe2Jim ;
+
+    use Filter::Util::Call ;
+
+    sub import
+    {
+        my($type) = @_ ;
+
+        filter_add(bless []) ;
+    }
+
+    sub filter
+    {
+        my($self) = @_ ;
+        my($status) ;
+
+        s/Joe/Jim/g
+            if ($status = filter_read()) > 0 ;
+        $status ;
+    }
+
+    1 ;
+
+Here is an example of using the filter:
+
+    use Joe2Jim ;
+    print "Where is Joe?\n" ;
+
+And this is what the script above will print:
+
+    Where is Jim?
+
+=head2 Example 2: Using the context
+
+The previous example was not particularly useful. To make it more
+general purpose we will make use of the context data and allow any
+arbitrary I<from> and I<to> strings to be used. This time we will use a
+I<closure filter>. To reflect its enhanced role, the filter is called
+C<Subst>.
+
+    package Subst ;
+
+    use Filter::Util::Call ;
+    use Carp ;
+
+    sub import
+    {
+        croak("usage: use Subst qw(from to)")
+            unless @_ == 3 ;
+        my ($self, $from, $to) = @_ ;
+        filter_add(
+            sub 
+            {
+                my ($status) ;
+                s/$from/$to/
+                    if ($status = filter_read()) > 0 ;
+                $status ;
+            })
+    }
+    1 ;
+
+and is used like this:
+
+    use Subst qw(Joe Jim) ;
+    print "Where is Joe?\n" ;
+
+
+=head2 Example 3: Using the context within the filter
+
+Here is a filter which a variation of the C<Joe2Jim> filter. As well as
+substituting all occurrences of C<"Joe"> to C<"Jim"> it keeps a count
+of the number of substitutions made in the context object.
+
+Once EOF is detected (C<$status> is zero) the filter will insert an
+extra line into the source stream. When this extra line is executed it
+will print a count of the number of substitutions actually made.
+Note that C<$status> is set to C<1> in this case.
+
+    package Count ;
+
+    use Filter::Util::Call ;
+
+    sub filter
+    {
+        my ($self) = @_ ;
+        my ($status) ;
+
+        if (($status = filter_read()) > 0 ) {
+            s/Joe/Jim/g ;
+           ++ $$self ;
+        }
+       elsif ($$self >= 0) { # EOF
+            $_ = "print q[Made ${$self} substitutions\n]" ;
+            $status = 1 ;
+           $$self = -1 ;
+        }
+
+        $status ;
+    }
+
+    sub import
+    {
+        my ($self) = @_ ;
+        my ($count) = 0 ;
+        filter_add(\$count) ;
+    }
+
+    1 ;
+
+Here is a script which uses it:
+
+    use Count ;
+    print "Hello Joe\n" ;
+    print "Where is Joe\n" ;
+
+Outputs:
+
+    Hello Jim
+    Where is Jim
+    Made 2 substitutions
+
+=head2 Example 4: Using filter_del
+
+Another variation on a theme. This time we will modify the C<Subst>
+filter to allow a starting and stopping pattern to be specified as well
+as the I<from> and I<to> patterns. If you know the I<vi> editor, it is
+the equivalent of this command:
+
+    :/start/,/stop/s/from/to/
+
+When used as a filter we want to invoke it like this:
+
+    use NewSubst qw(start stop from to) ;
+
+Here is the module.
+
+    package NewSubst ;
+
+    use Filter::Util::Call ;
+    use Carp ;
+
+    sub import
+    {
+        my ($self, $start, $stop, $from, $to) = @_ ;
+        my ($found) = 0 ;
+        croak("usage: use Subst qw(start stop from to)")
+            unless @_ == 5 ;
+
+        filter_add( 
+            sub 
+            {
+                my ($status) ;
+
+                if (($status = filter_read()) > 0) {
+
+                    $found = 1
+                        if $found == 0 and /$start/ ;
+
+                    if ($found) {
+                        s/$from/$to/ ;
+                        filter_del() if /$stop/ ;
+                    }
+
+                }
+                $status ;
+            } )
+
+    }
+
+    1 ;
+
+=head1 Filter::Simple
+
+If you intend using the Filter::Call functionality, I would strongly
+recommend that you check out Damian Conway's excellent Filter::Simple
+module. Damian's module provides a much cleaner interface than
+Filter::Util::Call. Although it doesn't allow the fine control that
+Filter::Util::Call does, it should be adequate for the majority of
+applications. It's available at
+
+   http://www.cpan.org/modules/by-author/Damian_Conway/Filter-Simple.tar.gz
+   http://www.csse.monash.edu.au/~damian/CPAN/Filter-Simple.tar.gz
+
+=head1 AUTHOR
+
+Paul Marquess 
+
+=head1 DATE
+
+26th January 1996
+
+=cut
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Call/Call.xs b/deb-src/libfilter-perl/libfilter-perl-1.34/Call/Call.xs
new file mode 100644 (file)
index 0000000..7755618
--- /dev/null
@@ -0,0 +1,262 @@
+/* 
+ * Filename : Call.xs
+ * 
+ * Author   : Paul Marquess 
+ * Date     : 11th November 2001
+ * Version  : 1.06
+ *
+ *    Copyright (c) 1995-2001 Paul Marquess. All rights reserved.
+ *       This program is free software; you can redistribute it and/or
+ *              modify it under the same terms as Perl itself.
+ *
+ */
+
+#define PERL_NO_GET_CONTEXT
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#ifdef _NOT_CORE
+#  include "ppport.h"
+#endif
+
+/* Internal defines */
+#define PERL_MODULE(s)         IoBOTTOM_NAME(s)
+#define PERL_OBJECT(s)         IoTOP_GV(s)
+#define FILTER_ACTIVE(s)       IoLINES(s)
+#define BUF_OFFSET(sv)         IoPAGE_LEN(sv)
+#define CODE_REF(sv)           IoPAGE(sv)
+#ifndef PERL_FILTER_EXISTS
+#  define PERL_FILTER_EXISTS(i) (PL_rsfp_filters && (i) <= av_len(PL_rsfp_filters))
+#endif
+
+#define SET_LEN(sv,len) \
+        do { SvPVX(sv)[len] = '\0'; SvCUR_set(sv, len); } while (0)
+
+
+/* Global Data */
+
+#define MY_CXT_KEY "Filter::Util::Call::_guts" XS_VERSION
+typedef struct {
+    int x_fdebug ;
+    int x_current_idx ;
+} my_cxt_t;
+START_MY_CXT
+#define fdebug          (MY_CXT.x_fdebug)
+#define current_idx     (MY_CXT.x_current_idx)
+
+
+static I32
+filter_call(pTHX_ int idx, SV *buf_sv, int maxlen)
+{
+    dMY_CXT;
+    SV   *my_sv = FILTER_DATA(idx);
+    char *nl = "\n";
+    char *p;
+    char *out_ptr;
+    int n;
+
+    if (fdebug)
+       warn("**** In filter_call - maxlen = %d, out len buf = %d idx = %d my_sv = %d [%s]\n", 
+               maxlen, SvCUR(buf_sv), idx, SvCUR(my_sv), SvPVX(my_sv) ) ;
+
+    while (1) {
+
+       /* anything left from last time */
+       if ((n = SvCUR(my_sv))) {
+
+           out_ptr = SvPVX(my_sv) + BUF_OFFSET(my_sv) ;
+
+           if (maxlen) { 
+               /* want a block */ 
+               if (fdebug)
+                   warn("BLOCK(%d): size = %d, maxlen = %d\n", 
+                       idx, n, maxlen) ;
+
+               sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
+               if(n <= maxlen) {
+                   BUF_OFFSET(my_sv) = 0 ;
+                   SET_LEN(my_sv, 0) ;
+               }
+               else {
+                   BUF_OFFSET(my_sv) += maxlen ;
+                   SvCUR_set(my_sv, n - maxlen) ;
+               }
+               return SvCUR(buf_sv);
+           }
+           else {
+               /* want lines */
+                if ((p = ninstr(out_ptr, out_ptr + n, nl, nl + 1))) {
+
+                   sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);
+
+                   n = n - (p - out_ptr + 1);
+                   BUF_OFFSET(my_sv) += (p - out_ptr + 1);
+                   SvCUR_set(my_sv, n) ;
+                   if (fdebug)
+                       warn("recycle %d - leaving %d, returning %d [%s]", 
+                               idx, n, SvCUR(buf_sv), SvPVX(buf_sv)) ;
+
+                   return SvCUR(buf_sv);
+               }
+               else /* no EOL, so append the complete buffer */
+                   sv_catpvn(buf_sv, out_ptr, n) ;
+           }
+           
+       }
+
+
+       SET_LEN(my_sv, 0) ;
+       BUF_OFFSET(my_sv) = 0 ;
+
+       if (FILTER_ACTIVE(my_sv))
+       {
+           dSP ;
+           int count ;
+
+            if (fdebug)
+               warn("gonna call %s::filter\n", PERL_MODULE(my_sv)) ;
+
+           ENTER ;
+           SAVETMPS;
+       
+           SAVEINT(current_idx) ;      /* save current idx */
+           current_idx = idx ;
+
+           SAVESPTR(DEFSV) ;   /* save $_ */
+           /* make $_ use our buffer */
+           DEFSV = sv_2mortal(newSVpv("", 0)) ; 
+
+           PUSHMARK(sp) ;
+
+           if (CODE_REF(my_sv)) {
+           /* if (SvROK(PERL_OBJECT(my_sv)) && SvTYPE(SvRV(PERL_OBJECT(my_sv))) == SVt_PVCV) { */
+               count = perl_call_sv((SV*)PERL_OBJECT(my_sv), G_SCALAR);
+           }
+           else {
+                XPUSHs((SV*)PERL_OBJECT(my_sv)) ;  
+       
+               PUTBACK ;
+
+               count = perl_call_method("filter", G_SCALAR);
+           }
+
+           SPAGAIN ;
+
+            if (count != 1)
+               croak("Filter::Util::Call - %s::filter returned %d values, 1 was expected \n", 
+                       PERL_MODULE(my_sv), count ) ;
+    
+           n = POPi ;
+
+           if (fdebug)
+               warn("status = %d, length op buf = %d [%s]\n",
+                    n, SvCUR(DEFSV), SvPVX(DEFSV) ) ;
+           if (SvCUR(DEFSV))
+               sv_setpvn(my_sv, SvPVX(DEFSV), SvCUR(DEFSV)) ; 
+
+           PUTBACK ;
+           FREETMPS ;
+           LEAVE ;
+       }
+       else
+           n = FILTER_READ(idx + 1, my_sv, maxlen) ;
+
+       if (n <= 0)
+       {
+           /* Either EOF or an error */
+
+           if (fdebug) 
+               warn ("filter_read %d returned %d , returning %d\n", idx, n,
+                   (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n);
+
+           /* PERL_MODULE(my_sv) ; */
+           /* PERL_OBJECT(my_sv) ; */
+           filter_del(filter_call); 
+
+           /* If error, return the code */
+           if (n < 0)
+               return n ;
+
+           /* return what we have so far else signal eof */
+           return (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n;
+       }
+
+    }
+}
+
+
+
+MODULE = Filter::Util::Call            PACKAGE = Filter::Util::Call
+
+REQUIRE:       1.924
+PROTOTYPES:    ENABLE
+
+#define IDX            current_idx
+
+int
+filter_read(size=0)
+       int     size 
+       CODE:
+       {
+           dMY_CXT;
+           SV * buffer = DEFSV ;
+
+           RETVAL = FILTER_READ(IDX + 1, buffer, size) ;
+       }
+       OUTPUT:
+           RETVAL
+
+
+
+
+void
+real_import(object, perlmodule, coderef)
+    SV *       object
+    char *     perlmodule 
+    int                coderef
+    PPCODE:
+    {
+        SV * sv = newSV(1) ;
+
+        (void)SvPOK_only(sv) ;
+        filter_add(filter_call, sv) ;
+
+       PERL_MODULE(sv) = savepv(perlmodule) ;
+       PERL_OBJECT(sv) = (GV*) newSVsv(object) ;
+       FILTER_ACTIVE(sv) = TRUE ;
+        BUF_OFFSET(sv) = 0 ;
+       CODE_REF(sv)   = coderef ;
+
+        SvCUR_set(sv, 0) ;
+
+    }
+
+void
+filter_del()
+    CODE:
+        dMY_CXT;
+       if (PERL_FILTER_EXISTS(IDX) && FILTER_DATA(IDX) && FILTER_ACTIVE(FILTER_DATA(IDX)))
+           FILTER_ACTIVE(FILTER_DATA(IDX)) = FALSE ;
+
+
+
+void
+unimport(package="$Package", ...)
+    char *package
+    PPCODE:
+    filter_del(filter_call);
+
+
+BOOT:
+  {
+    MY_CXT_INIT;
+    fdebug = 0;
+    /* temporary hack to control debugging in toke.c */
+    if (fdebug)
+        filter_add(NULL, (fdebug) ? (SV*)"1" : (SV*)"0");  
+  }
+
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Call/Makefile.PL b/deb-src/libfilter-perl/libfilter-perl-1.34/Call/Makefile.PL
new file mode 100755 (executable)
index 0000000..1ab017e
--- /dev/null
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+       NAME            => 'Filter::Util::Call',
+       DEFINE          => '-D_NOT_CORE',
+       VERSION_FROM    => 'Call.pm',
+);
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Call/ppport.h b/deb-src/libfilter-perl/libfilter-perl-1.34/Call/ppport.h
new file mode 100644 (file)
index 0000000..c264f43
--- /dev/null
@@ -0,0 +1,286 @@
+/* This file is Based on output from 
+ * Perl/Pollution/Portability Version 2.0000 */
+
+#ifndef _P_P_PORTABILITY_H_
+#define _P_P_PORTABILITY_H_
+
+#ifndef PERL_REVISION
+#   ifndef __PATCHLEVEL_H_INCLUDED__
+#       include "patchlevel.h"
+#   endif
+#   ifndef PERL_REVISION
+#      define PERL_REVISION    (5)
+        /* Replace: 1 */
+#       define PERL_VERSION    PATCHLEVEL
+#       define PERL_SUBVERSION SUBVERSION
+        /* Replace PERL_PATCHLEVEL with PERL_VERSION */
+        /* Replace: 0 */
+#   endif
+#endif
+
+#define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION)
+
+#ifndef ERRSV
+#      define ERRSV perl_get_sv("@",FALSE)
+#endif
+
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5))
+/* Replace: 1 */
+#      define PL_Sv            Sv
+#      define PL_compiling     compiling
+#      define PL_copline       copline
+#      define PL_curcop        curcop
+#      define PL_curstash      curstash
+#      define PL_defgv         defgv
+#      define PL_dirty         dirty
+#      define PL_hints         hints
+#      define PL_na            na
+#      define PL_perldb        perldb
+#      define PL_rsfp_filters  rsfp_filters
+#      define PL_rsfp          rsfp
+#      define PL_stdingv       stdingv
+#      define PL_sv_no         sv_no
+#      define PL_sv_undef      sv_undef
+#      define PL_sv_yes        sv_yes
+/* Replace: 0 */
+#endif
+
+#ifndef pTHX
+#    define pTHX
+#    define pTHX_
+#    define aTHX
+#    define aTHX_
+#endif         
+
+#ifndef PTR2IV
+#    define PTR2IV(d)   (IV)(d)
+#endif
+#ifndef INT2PTR
+#    define INT2PTR(any,d)      (any)(d)
+#endif
+
+#ifndef dTHR
+#  ifdef WIN32
+#      define dTHR extern int Perl___notused
+#  else
+#      define dTHR extern int errno
+#  endif
+#endif
+
+#ifndef boolSV
+#      define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
+#endif
+
+#ifndef gv_stashpvn
+#      define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
+#endif
+
+#ifndef newSVpvn
+#      define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0))
+#endif
+
+#ifndef Pid_t
+#    define Pid_t      pid_t
+#endif
+
+#ifndef newRV_inc
+/* Replace: 1 */
+#      define newRV_inc(sv) newRV(sv)
+/* Replace: 0 */
+#endif
+
+/* DEFSV appears first in 5.004_56 */
+#ifndef DEFSV
+#  define DEFSV        GvSV(PL_defgv)
+#endif
+
+#ifndef SAVE_DEFSV
+#    define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
+#endif
+
+#ifndef newRV_noinc
+#  ifdef __GNUC__
+#    define newRV_noinc(sv)               \
+      ({                                  \
+          SV *nsv = (SV*)newRV(sv);       \
+          SvREFCNT_dec(sv);               \
+          nsv;                            \
+      })
+#  else
+#    if defined(CRIPPLED_CC) || defined(USE_THREADS)
+static SV * newRV_noinc (SV * sv)
+{
+          SV *nsv = (SV*)newRV(sv);       
+          SvREFCNT_dec(sv);               
+          return nsv;                     
+}
+#    else
+#      define newRV_noinc(sv)    \
+        ((PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv)
+#    endif
+#  endif
+#endif
+
+/* Provide: newCONSTSUB */
+
+/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */
+#if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63))
+
+#if defined(NEED_newCONSTSUB)
+static
+#else
+extern void newCONSTSUB _((HV * stash, char * name, SV *sv));
+#endif
+
+#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL)
+void
+newCONSTSUB(stash,name,sv)
+HV *stash;
+char *name;
+SV *sv;
+{
+       U32 oldhints = PL_hints;
+       HV *old_cop_stash = PL_curcop->cop_stash;
+       HV *old_curstash = PL_curstash;
+       line_t oldline = PL_curcop->cop_line;
+       PL_curcop->cop_line = PL_copline;
+
+       PL_hints &= ~HINT_BLOCK_SCOPE;
+       if (stash)
+               PL_curstash = PL_curcop->cop_stash = stash;
+
+       newSUB(
+
+#if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22))
+     /* before 5.003_22 */
+               start_subparse(),
+#else
+#  if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22)
+     /* 5.003_22 */
+               start_subparse(0),
+#  else
+     /* 5.003_23  onwards */
+               start_subparse(FALSE, 0),
+#  endif
+#endif
+
+               newSVOP(OP_CONST, 0, newSVpv(name,0)),
+               newSVOP(OP_CONST, 0, &PL_sv_no),   /* SvPV(&PL_sv_no) == "" -- GMB */
+               newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
+       );
+
+       PL_hints = oldhints;
+       PL_curcop->cop_stash = old_cop_stash;
+       PL_curstash = old_curstash;
+       PL_curcop->cop_line = oldline;
+}
+#endif
+
+#endif /* newCONSTSUB */
+
+
+#ifndef START_MY_CXT
+
+/*
+ * Boilerplate macros for initializing and accessing interpreter-local
+ * data from C.  All statics in extensions should be reworked to use
+ * this, if you want to make the extension thread-safe.  See ext/re/re.xs
+ * for an example of the use of these macros.
+ *
+ * Code that uses these macros is responsible for the following:
+ * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts"
+ * 2. Declare a typedef named my_cxt_t that is a structure that contains
+ *    all the data that needs to be interpreter-local.
+ * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
+ * 4. Use the MY_CXT_INIT macro such that it is called exactly once
+ *    (typically put in the BOOT: section).
+ * 5. Use the members of the my_cxt_t structure everywhere as
+ *    MY_CXT.member.
+ * 6. Use the dMY_CXT macro (a declaration) in all the functions that
+ *    access MY_CXT.
+ */
+
+#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \
+    defined(PERL_CAPI)    || defined(PERL_IMPLICIT_CONTEXT)
+
+/* This must appear in all extensions that define a my_cxt_t structure,
+ * right after the definition (i.e. at file scope).  The non-threads
+ * case below uses it to declare the data as static. */
+#define START_MY_CXT
+
+#if PERL_REVISION == 5 && \
+    (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 ))
+/* Fetches the SV that keeps the per-interpreter data. */
+#define dMY_CXT_SV \
+       SV *my_cxt_sv = perl_get_sv(MY_CXT_KEY, FALSE)
+#else /* >= perl5.004_68 */
+#define dMY_CXT_SV \
+       SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY,             \
+                                 sizeof(MY_CXT_KEY)-1, TRUE)
+#endif /* < perl5.004_68 */
+
+/* This declaration should be used within all functions that use the
+ * interpreter-local data. */
+#define dMY_CXT        \
+       dMY_CXT_SV;                                                     \
+       my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))
+
+/* Creates and zeroes the per-interpreter data.
+ * (We allocate my_cxtp in a Perl SV so that it will be released when
+ * the interpreter goes away.) */
+#define MY_CXT_INIT \
+       dMY_CXT_SV;                                                     \
+       /* newSV() allocates one more than needed */                    \
+       my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
+       Zero(my_cxtp, 1, my_cxt_t);                                     \
+       sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+
+/* This macro must be used to access members of the my_cxt_t structure.
+ * e.g. MYCXT.some_data */
+#define MY_CXT         (*my_cxtp)
+
+/* Judicious use of these macros can reduce the number of times dMY_CXT
+ * is used.  Use is similar to pTHX, aTHX etc. */
+#define pMY_CXT                my_cxt_t *my_cxtp
+#define pMY_CXT_       pMY_CXT,
+#define _pMY_CXT       ,pMY_CXT
+#define aMY_CXT                my_cxtp
+#define aMY_CXT_       aMY_CXT,
+#define _aMY_CXT       ,aMY_CXT
+
+#else /* single interpreter */
+
+#ifndef NOOP
+#  define NOOP (void)0
+#endif
+
+#ifdef HASATTRIBUTE
+#  define PERL_UNUSED_DECL __attribute__((unused))
+#else
+#  define PERL_UNUSED_DECL
+#endif    
+
+#ifndef dNOOP
+#  define dNOOP extern int Perl___notused PERL_UNUSED_DECL
+#endif
+
+#define START_MY_CXT   static my_cxt_t my_cxt;
+#define dMY_CXT_SV     dNOOP
+#define dMY_CXT                dNOOP
+#define MY_CXT_INIT    NOOP
+#define MY_CXT         my_cxt
+
+#define pMY_CXT                void
+#define pMY_CXT_
+#define _pMY_CXT
+#define aMY_CXT
+#define aMY_CXT_
+#define _aMY_CXT
+
+#endif 
+
+#endif /* START_MY_CXT */
+
+
+#endif /* _P_P_PORTABILITY_H_ */
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Changes b/deb-src/libfilter-perl/libfilter-perl-1.34/Changes
new file mode 100644 (file)
index 0000000..8367b12
--- /dev/null
@@ -0,0 +1,292 @@
+
+1.02 Tuesday 20th June 1995
+----
+
+    * First release.
+
+1.03 Sunday 25th June 1995
+----
+
+    * Tidied up the build process so that it doesn't need an empty
+      Filter.xs file.
+
+1.04 Sunday 25th June 1995
+----
+
+    * The test harness now uses $^X to invoke Perl.
+
+
+1.05 Monday 26th June 1995
+----
+
+   * updated MANIFEST
+
+   * tee.t test 5 has been hard-wired to return true if run as root.
+
+   * The test files don't use $^X to invoke perl any more. I've passed
+     the MakeMaker symbol FULLPERL via an environment variable. A bit
+     of a kludge, but it does work :-)
+
+   * added a mytest target to allow users to play with the Filters
+     without having to install them.
+
+   * The EWOULDBLOCK/EAGAIN stuff has been wrapped in preprocessor code.
+
+   * The hints files don't seem to be needed anymore.
+
+
+1.06 Sunday 2nd July 1995
+----
+
+    * Renamed decrypt.test to decrypt.tst.
+
+    * Renamed mytest.pl to mytest - it was getting installed.
+
+    * exec.xs had a bit of debugging code lurking around. This meant
+      that O_NONBLOCK was *always* being used to set non-blocking i/o.
+      This has been removed.
+
+    * Changed the way O_NONBLOCK/O_NDELAY was being detected. The Tk
+      method is now used.
+
+    * Addition of Filter::call - first go at implementation of perl filters.
+
+
+1.07 Wednesday 29th November 1995
+----
+
+  * exec now uses the non-blocking IO constants from Configure. Thanks
+    to Raphael for writing the dist module and to Andy for including it
+    in Configure.
+  * The decrypt filter has been enhanced to detect when it is
+    executing as a dynamically linked module and if DEBUGGING is
+    enabled. Thanks to Tim for providing the dynamic module test.
+  * Tim provided a pile of bug fixes for decrypt.xs
+  * Filter::call has been renamed Filter::Util::Call and the logic for
+    installing it has been changed. 
+  * The workings of the filter method in Filter::Util::Call has been
+    changed.
+
+
+1.08 Friday 15th December 1995
+----
+
+  * Fixed a bug in Exec.xs - wait was being called without a parameter.
+
+  * Added a closure option to Call
+
+
+1.09 Wednesday 22nd April 1996
+----
+
+  * Fixed a warning in Exec.xs - added a cast to safefree
+
+  * Makefile.PL now uses VERSION_FROM
+
+  * Made all filter modules strict clean.
+
+  * The simple encrypt script supplied with the decryption filter will
+    now preserve the original file permissions. In addition if the
+    first line of the script begins with "#!", the line will be
+    preserved in the encrypted version.
+
+1.10 Thursday 20th June 1996
+----
+
+  * decrypt now calls filter_del.
+
+1.11 Tuesday 29th October 1996
+----
+
+  * test harness for decrypt doesn't display the debugger banner
+    message any more.
+
+  * casted uses of IoTOP_GV in Call.xs, decrypt.xs and Exec.xs to keep
+    the IRIX compiler happy.
+
+1.12 Tuesday 25th March 1997
+----
+
+  * Patch from Andreas Koenig to make tee.xs compile when useperio is
+    enabled.
+
+  * Fix Call interface to work with 5.003_94
+
+
+1.13 Monday 29th December 1997
+----
+
+  * added the order test harness.
+
+  * patch from Gurusamy Sarathy to get the filters to build and pass
+    all tests on NT.
+
+1.14 Thursday 1st January 1998
+----
+
+  * patch from Gurusamy Sarathy to allow the filters to build when
+    threading is enabled.
+
+1.15 Monday 26th October 1998
+----
+
+  * Fixed a bug in the tee filter. 
+
+  * Applied patch from Gurusamy Sarathy which prevents Exec from coredump
+    when perl |is run with PERL_DESTRUCT_LEVEL.
+
+1.16 wednesday 17th March 1999
+----
+
+  * Upgraded to use the new PL_* symbols. Means the module can build with 
+    Perl5.005_5*.
+
+1.17 Friday 10th December 1999
+----
+
+  * Addition of perlfilter.pod. This is the Source Filters article from
+    The Perl Journal, issue 11 and is identical to the file that is
+    distributed with Perl starting withversion 5.005_63.
+
+1.18 Sunday 2nd April 2000
+----
+
+  * Test harnesses are more robust on Win32.
+
+  * Fixed a problem where an __END__ or __DATA__ could crash Perl.
+
+1.19 Thursday 20th July 2000
+----
+
+  * Added a test in decrypt.xs to check if the Compiler backend is in use.
+    Thanks to Andrew Johnson for bringing this to my attention.
+
+1.20 Sunday 7th January 2001
+----
+
+  * Added a SYNOPSIS to Call.pm & Exec.pm
+
+  * Integrated perl core patches 7849, 7913 & 7931.
+
+  * Modified decrypt.t to fix a case where HP-UX didn't pass test 4.
+
+
+1.21 Monday 19th February 20001
+----
+
+  * Added logic in Makefile.PL to toggle between using $^W and
+    the warnings pragma in the module.
+  * The module, the examples & the test harness are now all strict
+    & warnings clean.  
+
+1.22 Wednesday 21st February 20001
+----
+
+  * Added Michael G Schwern's example of a practical use of Filter::cpp
+    into the pod.
+
+  * Filter::cpp assumed that cpp.exe is always available on MSWin32. Logic
+    has been added to check for the existence of cpp.exe.
+
+  * Added a reference to Damian Conway's excellent Filter::Simple module.
+
+  * Merged Core patch 9176
+
+1.23 Monday 23rd April 2001
+----
+
+  * Modified Makefile.PL to only enable the warnings pragma if using perl
+    5.6.1 or better.    
+
+1.24 
+----
+
+  * Fixed sh.t, exec.t & cpp.t to work properly on NT 
+    patch courtesy of Steve Hay.
+
+  * The detection of cpp in cpp.pm is now more robust
+    patch courtesy of Michael Schwern
+
+  * Changed na to PL_na in decrypt.xs
+
+  * Merged Core patches 10752, 11434
+
+1.25 
+----
+
+  * Fixed minor typo in Makefile.PL
+
+1.26 
+----
+
+  * Call & Exec now use the CXT* macros
+
+  * moved all backward compatability code into ppport.h
+
+1.27 
+----
+
+  * Patch from Wim Verhaegen to allow cpp to be an absolute path 
+
+  * Patch from Gurusamy Sarathy to fix a Windods core dump in Exec.xs --
+    dMY_CXT was being accessed before it was ititialised.
+
+  * Merged core patch 13940
+
+1.28 
+----
+
+  * Fixed bug in Filter::cpp where $Config{cppstdin} refered to an executable
+    with an absolute path. Bug spotted by P. Kent.
+
+1.29 29 June 2002
+----
+
+  * Fixed problem with sleep in Exec.xs. Patch provided by Charles Randall.
+
+  * Exec.xs now used waitpid, when available, instead or wait. Patch provided
+    by Richard Clamp. 
+
+  * Also the place where the wait is called has been changed.
+    Deadlock condition spotted by Andrej Czapszys.
+
+1.30 16 August 2003
+----
+
+  * rewording of reference to Filter::Simple 
+
+  * merged core patch 18269
+
+1.31 31 August 2005
+----
+
+  * added 'libscan' to Makefile.PL to stop .bak files being installed.
+    [rt.cpan.org: Ticket #14356 .bak files are being installed ]
+
+1.32 3 January 2006
+----
+
+  * Added core patch 26509 -- fix out by one bug in Call.xs
+    Problem reported & fixed by Gisle Aas.
+
+1.33 1 March 2007
+----
+
+  * fixed ninstr issue for 5.8.9
+
+  * added t/pod.t
+
+1.34 7 July 2007
+----
+
+  * Included Core patch #31200 - change to support perl 5.10 for
+    Filter::Util::Call
+
+  * Also included the equivalent changes for the other filters. Patch
+    kindly provided by Steve Hay.
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Exec.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Exec.pm
new file mode 100644 (file)
index 0000000..9d1150a
--- /dev/null
@@ -0,0 +1,40 @@
+package Filter::Util::Exec ;
+
+require 5.002 ;
+require DynaLoader;
+use strict;
+use warnings;
+use vars qw(@ISA $VERSION) ;
+@ISA = qw(DynaLoader);
+$VERSION = "1.03" ;
+
+bootstrap Filter::Util::Exec ;
+1 ;
+__END__
+
+=head1 NAME
+
+Filter::Util::Exec - exec source filter
+
+=head1 SYNOPSIS
+    use Filter::Util::Exec;
+
+=head1 DESCRIPTION
+
+This module is provides the interface to allow the creation of I<Source
+Filters> which use a Unix coprocess.
+
+See L<Filter::exec>, L<Filter::cpp> and L<Filter::sh> for examples of
+the use of this module.
+
+=head1 AUTHOR
+
+Paul Marquess 
+
+=head1 DATE
+
+11th December 1995.
+
+=cut
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Exec.xs b/deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Exec.xs
new file mode 100644 (file)
index 0000000..2b7ae13
--- /dev/null
@@ -0,0 +1,625 @@
+/* 
+ * Filename : exec.xs
+ * 
+ * Author   : Paul Marquess 
+ * Date     : 26th March 2000
+ * Version  : 1.05
+ *
+ */
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "../Call/ppport.h"
+
+#include <fcntl.h>
+
+/* Global Data */
+#define MY_CXT_KEY "Filter::Util::Exec::_guts" XS_VERSION
+typedef struct {
+    int x_fdebug ;
+#ifdef WIN32
+    int x_write_started;
+    int x_pipe_pid;
+#endif
+} my_cxt_t;
+START_MY_CXT
+#define fdebug          (MY_CXT.x_fdebug)
+#ifdef WIN32
+#define write_started  (MY_CXT.x_write_started)    
+#define pipe_pid       (MY_CXT.x_pipe_pid)    
+#endif
+
+#ifdef PERL_FILTER_EXISTS
+#  define CORE_FILTER_SCRIPT PL_parser->rsfp
+#else
+#  define CORE_FILTER_SCRIPT PL_rsfp
+#endif
+
+
+#define PIPE_IN(sv)    IoLINES(sv)
+#define PIPE_OUT(sv)   IoPAGE(sv)
+#define PIPE_PID(sv)   IoLINES_LEFT(sv)
+
+#define BUF_SV(sv)     IoTOP_GV(sv)
+#define BUF_START(sv)  SvPVX((SV*) BUF_SV(sv))
+#define BUF_SIZE(sv)   SvCUR((SV*) BUF_SV(sv))
+#define BUF_NEXT(sv)   IoFMT_NAME(sv)
+#define BUF_END(sv)    (BUF_START(sv) + BUF_SIZE(sv))
+#define BUF_OFFSET(sv)  IoPAGE_LEN(sv) 
+#define SET_LEN(sv,len) \
+        do { SvPVX(sv)[len] = '\0'; SvCUR_set(sv, len); } while (0)
+#define BLOCKSIZE       100
+
+
+#ifdef WIN32
+
+typedef struct {
+    SV *       sv;
+    int                idx;
+#ifdef USE_THREADS
+    struct perl_thread *       parent;
+#endif
+#ifdef USE_ITHREADS
+    PerlInterpreter *          parent;
+#endif
+} thrarg;
+
+static void
+pipe_write(void *args)
+{
+    thrarg *targ = (thrarg *)args;
+    SV *sv = targ->sv;
+    int idx = targ->idx;
+    int    pipe_in  = PIPE_IN(sv) ;
+    int    pipe_out = PIPE_OUT(sv) ;
+    int rawread_eof = 0;
+    int r,w,len;
+#ifdef USE_THREADS
+    /* use the parent's perl thread context */
+    SET_THR(targ->parent);
+#endif
+#ifdef USE_ITHREADS
+    PERL_SET_THX(targ->parent);
+#endif
+    {
+    dMY_CXT;
+    free(args);
+    for(;;)
+    {       
+
+        /* get some raw data to stuff down the pipe */
+       /* But only when BUF_SV is empty */
+        if (!rawread_eof && BUF_NEXT(sv) >= BUF_END(sv)) {       
+           /* empty BUF_SV */
+           SvCUR_set((SV*)BUF_SV(sv), 0) ;
+            if ((len = FILTER_READ(idx+1, (SV*) BUF_SV(sv), 0)) > 0) {
+               BUF_NEXT(sv) = BUF_START(sv);
+                if (fdebug)
+                    warn ("*pipe_write(%d) Filt Rd returned %d %d [%*s]\n", 
+                       idx, len, BUF_SIZE(sv), BUF_SIZE(sv), BUF_START(sv)) ;
+            }
+             else {
+                /* eof, close write end of pipe after writing to it */
+                rawread_eof = 1;
+            }
+       }
+       /* write down the pipe */
+        if ((w = BUF_END(sv) - BUF_NEXT(sv)) > 0) {
+           errno = 0;
+            if ((w = write(pipe_out, BUF_NEXT(sv), w)) > 0) {
+               BUF_NEXT(sv) += w;
+               if (fdebug)
+                   warn ("*pipe_write(%d) wrote %d bytes to pipe\n", idx, w) ;
+           }
+            else {
+                if (fdebug)
+                   warn ("*pipe_write(%d) closing pipe_out errno = %d %s\n", 
+                       idx, errno, Strerror(errno)) ;
+                close(pipe_out) ;
+               CloseHandle((HANDLE)pipe_pid);
+               write_started = 0;
+               return;
+           }
+       }
+       else if (rawread_eof) {
+            if (fdebug)
+               warn ("*pipe_write(%d) closing pipe_out errno = %d %s\n", 
+               idx, errno, Strerror(errno)) ;
+           close(pipe_out);
+           CloseHandle((HANDLE)pipe_pid);
+           write_started = 0;
+           return;
+       }
+    }
+    }
+}
+
+static int
+pipe_read(SV *sv, int idx, int maxlen)
+{
+    dMY_CXT;
+    int    pipe_in  = PIPE_IN(sv) ;
+    int    pipe_out = PIPE_OUT(sv) ;
+
+    int r ;
+    int w ;
+    int len ;
+
+    if (fdebug)
+        warn ("*pipe_read(sv=%d, SvCUR(sv)=%d, idx=%d, maxlen=%d\n",
+               sv, SvCUR(sv), idx, maxlen) ;
+
+    if (!maxlen)
+       maxlen = 1024 ;
+
+    /* just make sure the SV is big enough */
+    SvGROW(sv, SvCUR(sv) + maxlen) ;
+
+    if ( !BUF_NEXT(sv) )
+        BUF_NEXT(sv) = BUF_START(sv);
+
+    if (!write_started) {
+       thrarg *targ = (thrarg*)malloc(sizeof(thrarg));
+       targ->sv = sv; targ->idx = idx;
+#ifdef USE_THREADS
+       targ->parent = THR;
+#endif
+#ifdef USE_ITHREADS
+       targ->parent = aTHX;
+#endif
+       /* thread handle is closed when pipe_write() returns */
+       _beginthread(pipe_write,0,(void *)targ);
+       write_started = 1;
+    }
+
+    /* try to get data from filter, if any */
+    errno = 0;
+    len = SvCUR(sv) ;
+    if ((r = read(pipe_in, SvPVX(sv) + len, maxlen)) > 0)
+    {
+       if (fdebug)
+           warn ("*pipe_read(%d) from pipe returned %d [%*s]\n", 
+                       idx, r, r, SvPVX(sv) + len) ;
+       SvCUR_set(sv, r + len) ;
+       return SvCUR(sv);
+    }
+
+    if (fdebug)
+       warn ("*pipe_read(%d) returned %d, errno = %d %s\n", 
+               idx, r, errno, Strerror(errno)) ;
+
+    /* close the read pipe on error/eof */
+    if (fdebug)
+       warn("*pipe_read(%d) -- EOF <#########\n", idx) ;
+    close (pipe_in) ; 
+    return 0;
+}
+
+#else /* !WIN32 */
+
+
+static int
+pipe_read(SV *sv, int idx, int maxlen)
+{
+    dMY_CXT;
+    int    pipe_in  = PIPE_IN(sv) ;
+    int    pipe_out = PIPE_OUT(sv) ;
+    int    pipe_pid = PIPE_PID(sv) ;
+
+    int r ;
+    int w ;
+    int len ;
+
+    if (fdebug)
+        warn ("*pipe_read(sv=%d, SvCUR(sv)=%d, idx=%d, maxlen=%d\n",
+               sv, SvCUR(sv), idx, maxlen) ;
+
+    if (!maxlen)
+       maxlen = 1024 ;
+
+    /* just make sure the SV is big enough */
+    SvGROW(sv, SvCUR(sv) + maxlen) ;
+
+    for(;;)
+    {       
+       if ( !BUF_NEXT(sv) )
+            BUF_NEXT(sv) = BUF_START(sv);
+        else
+        {       
+           /* try to get data from filter, if any */
+            errno = 0;
+           len = SvCUR(sv) ;
+            if ((r = read(pipe_in, SvPVX(sv) + len, maxlen)) > 0)
+           {
+                if (fdebug)
+                    warn ("*pipe_read(%d) from pipe returned %d [%*s]\n", 
+                               idx, r, r, SvPVX(sv) + len) ;
+               SvCUR_set(sv, r + len) ;
+                return SvCUR(sv);
+           }
+
+            if (fdebug)
+                warn ("*pipe_read(%d) returned %d, errno = %d %s\n", 
+                       idx, r, errno, Strerror(errno)) ;
+
+            if (errno != VAL_EAGAIN)
+           {
+               /* close the read pipe on error/eof */
+               if (fdebug)
+                   warn("*pipe_read(%d) -- EOF <#########\n", idx) ;
+               close (pipe_in) ; 
+#ifdef HAVE_WAITPID
+                waitpid(pipe_pid, NULL, 0) ;
+#else
+               wait(NULL);
+#endif
+                return 0;
+           }
+        }
+
+        /* get some raw data to stuff down the pipe */
+       /* But only when BUF_SV is empty */
+        if (BUF_NEXT(sv) >= BUF_END(sv))
+        {       
+           /* empty BUF_SV */
+           SvCUR_set((SV*)BUF_SV(sv), 0) ;
+            if ((len = FILTER_READ(idx+1, (SV*) BUF_SV(sv), 0)) > 0) {
+               BUF_NEXT(sv) = BUF_START(sv);
+                if (fdebug)
+                    warn ("*pipe_write(%d) Filt Rd returned %d %d [%*s]\n", 
+                       idx, len, BUF_SIZE(sv), BUF_SIZE(sv), BUF_START(sv)) ;
+            }
+             else {
+                /* eof, close write end of pipe */
+                close(pipe_out) ; 
+                if (fdebug)
+                    warn ("*pipe_read(%d) closing pipe_out errno = %d %s\n", 
+                               idx, errno,
+                       Strerror(errno)) ;
+            }
+         }
+        /* write down the pipe */
+         if ((w = BUF_END(sv) - BUF_NEXT(sv)) > 0)
+         {       
+            errno = 0;
+             if ((w = write(pipe_out, BUF_NEXT(sv), w)) > 0) {
+                 BUF_NEXT(sv) += w;
+                 if (fdebug)
+                    warn ("*pipe_read(%d) wrote %d bytes to pipe\n", idx, w) ;
+            }
+            else if (errno != VAL_EAGAIN) {
+                 if (fdebug)
+                    warn ("*pipe_read(%d) closing pipe_out errno = %d %s\n", 
+                               idx, errno, Strerror(errno)) ;
+                 /* close(pipe_out) ; */
+                 return 0;
+            }
+             else {    /* pipe is full, sleep for a while, then continue */
+                 if (fdebug)
+                    warn ("*pipe_read(%d) - sleeping\n", idx ) ;
+                sleep(0);
+            }
+        }
+    }
+}
+
+
+static void
+make_nonblock(int f)
+{
+   int RETVAL ;
+   int mode = fcntl(f, F_GETFL);
+   if (mode < 0)
+        croak("fcntl(f, F_GETFL) failed, RETVAL = %d, errno = %d",
+                mode, errno) ;
+   if (!(mode & VAL_O_NONBLOCK))
+       RETVAL = fcntl(f, F_SETFL, mode | VAL_O_NONBLOCK);
+    if (RETVAL < 0)
+        croak("cannot create a non-blocking pipe, RETVAL = %d, errno = %d",
+                RETVAL, errno) ;
+}
+#endif
+
+
+#define READER 0
+#define        WRITER  1
+
+static Pid_t
+spawnCommand(PerlIO *fil, char *command, char *parameters[], int *p0, int *p1) 
+{
+    dMY_CXT;
+#ifdef WIN32
+
+#if defined(PERL_OBJECT)
+#  define win32_pipe(p,n,f) _pipe(p,n,f)
+#endif
+
+    int p[2], c[2];
+    SV * sv ;
+    int oldstdout, oldstdin;
+
+    /* create the pipes */
+    if (win32_pipe(p,512,O_TEXT|O_NOINHERIT) == -1
+       || win32_pipe(c,512,O_BINARY|O_NOINHERIT) == -1) {
+       PerlIO_close( fil );
+       croak("Can't get pipe for %s", command);
+    }
+
+    /* duplicate stdout and stdin */
+    oldstdout = dup(fileno(stdout));
+    if (oldstdout == -1) {
+       PerlIO_close( fil );
+       croak("Can't dup stdout for %s", command);
+    }
+    oldstdin  = dup(fileno(stdin));
+    if (oldstdin == -1) {
+       PerlIO_close( fil );
+       croak("Can't dup stdin for %s", command);
+    }
+
+    /* duplicate inheritable ends as std handles for the child */
+    if (dup2(p[WRITER], fileno(stdout))) {
+       PerlIO_close( fil );
+       croak("Can't attach pipe to stdout for %s", command);
+    }
+    if (dup2(c[READER], fileno(stdin))) {
+       PerlIO_close( fil );
+       croak("Can't attach pipe to stdin for %s", command);
+    }
+
+    /* close original inheritable ends in parent */
+    close(p[WRITER]);
+    close(c[READER]);
+
+    /* spawn child process (which inherits the redirected std handles) */
+    pipe_pid = spawnvp(P_NOWAIT, command, parameters);
+    if (pipe_pid == -1) {
+       PerlIO_close( fil );
+       croak("Can't spawn %s", command);
+    }
+
+    /* restore std handles */
+    if (dup2(oldstdout, fileno(stdout))) {
+       PerlIO_close( fil );
+       croak("Can't restore stdout for %s", command);
+    }
+    if (dup2(oldstdin, fileno(stdin))) {
+       PerlIO_close( fil );
+       croak("Can't restore stdin for %s", command);
+    }
+
+    /* close saved handles */
+    close(oldstdout);
+    close(oldstdin);
+
+    *p0 = p[READER] ;
+    *p1 = c[WRITER] ;
+
+#else /* !WIN32 */
+
+    int p[2], c[2];
+    SV * sv ;
+    int        pipepid;
+
+    /* Check that the file is seekable */
+    /* if (lseek(fileno(fil), ftell(fil), 0) == -1) { */
+       /* croak("lseek failed: %s", Strerror(errno)) ; */
+    /* }  */
+
+    if (pipe(p) < 0 || pipe(c)) {
+       PerlIO_close( fil );
+       croak("Can't get pipe for %s", command);
+    }
+
+    /* make sure that the child doesn't get anything extra */
+    fflush(stdout);
+    fflush(stderr);
+
+    while ((pipepid = fork()) < 0) {
+       if (errno != EAGAIN) {
+           close(p[0]);
+           close(p[1]);
+           close(c[0]) ;
+           close(c[1]) ;
+           PerlIO_close( fil );
+           croak("Can't fork for %s", command);
+       }
+       sleep(1);
+    }
+
+    if (pipepid == 0) {
+       /* The Child */
+
+       close(p[READER]) ;
+       close(c[WRITER]) ;
+       if (c[READER] != 0) {
+           dup2(c[READER], 0);
+           close(c[READER]); 
+       }
+       if (p[WRITER] != 1) {
+           dup2(p[WRITER], 1);
+           close(p[WRITER]); 
+       }
+
+       /* Run command */
+       execvp(command, parameters) ;
+        croak("execvp failed for command '%s': %s", command, Strerror(errno)) ;
+       fflush(stdout);
+       fflush(stderr);
+       _exit(0);
+    }
+
+    /* The parent */
+
+    close(p[WRITER]) ;
+    close(c[READER]) ;
+
+    /* make the pipe non-blocking */
+    make_nonblock(p[READER]) ;
+    make_nonblock(c[WRITER]) ;
+
+    *p0 = p[READER] ;
+    *p1 = c[WRITER] ;
+
+    return pipepid;
+#endif
+}
+
+
+static I32
+filter_exec(pTHX_ int idx, SV *buf_sv, int maxlen)
+{
+    dMY_CXT;
+    I32 len;
+    SV   *buffer = FILTER_DATA(idx);
+    char * out_ptr = SvPVX(buffer) ;
+    int        n ;
+    char *     p ;
+    char *     nl = "\n" ;
+    if (fdebug)
+        warn ("filter_sh(idx=%d, SvCUR(buf_sv)=%d, maxlen=%d\n", 
+               idx, SvCUR(buf_sv), maxlen) ;
+    while (1) {
+       STRLEN n_a;
+
+        /* If there was a partial line/block left from last time
+           copy it now
+        */
+        if (n = SvCUR(buffer)) {
+           out_ptr  = SvPVX(buffer) + BUF_OFFSET(buffer) ;
+           if (maxlen) { 
+               /* want a block */
+               if (fdebug)
+                   warn("filter_sh(%d) - wants a block\n", idx) ;
+                sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
+                if(n <= maxlen) {
+                   BUF_OFFSET(buffer) = 0 ;
+                    SET_LEN(buffer, 0) ; 
+               }
+                else {
+                   BUF_OFFSET(buffer) += maxlen ;
+                    SvCUR_set(buffer, n - maxlen) ;
+                }
+                return SvCUR(buf_sv);
+           }
+           else {
+               /* want a line */
+               if (fdebug)
+                   warn("filter_sh(%d) - wants a line\n", idx) ;
+                if (p = ninstr(out_ptr, out_ptr + n, nl, nl + 1)) {
+                    sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);
+                    n = n - (p - out_ptr + 1);
+                   BUF_OFFSET(buffer) += (p - out_ptr + 1);
+                    SvCUR_set(buffer, n) ;
+                    if (fdebug)
+                        warn("recycle(%d) - leaving %d [%s], returning %d %d [%s]", 
+                               idx, n, 
+                               SvPVX(buffer), p - out_ptr + 1, 
+                               SvCUR(buf_sv), SvPVX(buf_sv)) ;
+     
+                    return SvCUR(buf_sv);
+                }
+                else /* partial buffer didn't have any newlines, so copy it all */
+                   sv_catpvn(buf_sv, out_ptr, n) ;
+           }
+        }
+
+       /* the buffer has been consumed, so reset the length */
+       SET_LEN(buffer, 0) ; 
+        BUF_OFFSET(buffer) = 0 ;
+
+        /* read from the sub-process */
+        if ( (n=pipe_read(buffer, idx, maxlen)) <= 0) {
+            if (fdebug)
+                warn ("filter_sh(%d) - pipe_read returned %d , returning %d\n", 
+                       idx, n, (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n);
+            SvCUR_set(buffer, 0);
+           BUF_NEXT(buffer) = Nullch;  /* or perl will try to free() it */
+            /* filter_del(filter_sh);  */
+            /* If error, return the code */
+            if (n < 0)
+                return n ;
+            /* return what we have so far else signal eof */
+            return (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n;
+        }
+        if (fdebug)
+            warn("  filter_sh(%d): pipe_read returned %d %d: '%s'",
+                idx, n, SvCUR(buffer), SvPV(buffer,n_a));
+    }
+
+}
+
+
+MODULE = Filter::Util::Exec    PACKAGE = Filter::Util::Exec
+
+REQUIRE:       1.924
+PROTOTYPES:    ENABLE
+
+BOOT:
+  {
+    MY_CXT_INIT;
+    fdebug = 0;
+    /* temporary hack to control debugging in toke.c */
+    filter_add(NULL, (fdebug) ? (SV*)"1" : (SV*)"0"); 
+  }
+
+
+void
+filter_add(module, command, ...)
+    SV *       module = NO_INIT
+    char **    command = (char**) safemalloc(items * sizeof(char*)) ;
+    PROTOTYPE: $@
+    CODE:
+       dMY_CXT;
+       int i ;
+       int pipe_in, pipe_out ;
+       STRLEN n_a ;
+       /* SV * sv = newSVpv("", 0) ; */
+       SV * sv = newSV(1) ;
+       Pid_t pid;
+      if (fdebug)
+          warn("Filter::exec::import\n") ;
+      for (i = 1 ; i < items ; ++i)
+      {
+          command[i-1] = SvPV(ST(i), n_a) ;
+         if (fdebug)
+             warn("    %s\n", command[i-1]) ;
+      }
+      command[i-1] = NULL ;
+      filter_add(filter_exec, sv);
+      pid = spawnCommand(CORE_FILTER_SCRIPT, command[0], command, &pipe_in, &pipe_out) ;
+      safefree((char*)command) ;
+
+      PIPE_PID(sv)  = pid ;
+      PIPE_IN(sv)   = pipe_in ;
+      PIPE_OUT(sv)  = pipe_out ;
+      /* BUF_SV(sv)    = newSVpv("", 0) ; */
+      BUF_SV(sv)    = (GV*) newSV(1) ;
+      (void)SvPOK_only(BUF_SV(sv)) ;
+      BUF_NEXT(sv)  = NULL ;
+      BUF_OFFSET(sv) = 0 ;
+
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Makefile.PL b/deb-src/libfilter-perl/libfilter-perl-1.34/Exec/Makefile.PL
new file mode 100755 (executable)
index 0000000..5b8974a
--- /dev/null
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+       NAME      => 'Filter::Util::Exec',
+       VERSION_FROM  => 'Exec.pm',
+);
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/MANIFEST b/deb-src/libfilter-perl/libfilter-perl-1.34/MANIFEST
new file mode 100644 (file)
index 0000000..c3d7be5
--- /dev/null
@@ -0,0 +1,49 @@
+Changes
+MANIFEST
+Makefile.PL
+README
+Call/Makefile.PL
+Call/Call.pm
+Call/Call.xs
+Call/ppport.h
+Exec/Makefile.PL
+Exec/Exec.pm
+Exec/Exec.xs
+decrypt/Makefile.PL
+decrypt/decr
+decrypt/decrypt.pm
+decrypt/decrypt.xs
+decrypt/encrypt
+examples/method/Count.pm       
+examples/method/NewSubst.pm    
+examples/method/UUdecode.pm
+examples/method/Decompress.pm  
+examples/method/Joe2Jim.pm  
+examples/method/Subst.pm       
+examples/closure/Count.pm       
+examples/closure/NewSubst.pm    
+examples/closure/UUdecode.pm
+examples/closure/Decompress.pm  
+examples/closure/Include.pm  
+examples/closure/Joe2Jim.pm  
+examples/closure/Subst.pm       
+examples/filtdef
+examples/filtuu
+lib/Filter/cpp.pm
+lib/Filter/exec.pm
+lib/Filter/sh.pm
+mytest
+t/call.t
+t/cpp.t
+t/decrypt.t
+t/exec.t
+t/order.t
+t/pod.t
+t/sh.t
+t/tee.t
+tee/Makefile.PL
+tee/tee.pm
+tee/tee.xs
+filter-util.pl
+perlfilter.pod
+META.yml                                 Module meta-data (added by MakeMaker)
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/META.yml b/deb-src/libfilter-perl/libfilter-perl-1.34/META.yml
new file mode 100644 (file)
index 0000000..ef3166e
--- /dev/null
@@ -0,0 +1,13 @@
+--- #YAML:1.0
+name:                Filter
+version:             1.34
+abstract:            Source Filters
+license:             perl
+generated_by:        ExtUtils::MakeMaker version 6.36
+distribution_type:   module
+requires:     
+meta-spec:
+    url:     http://module-build.sourceforge.net/META-spec-v1.2.html
+    version: 1.2
+author:
+    - Paul Marquess <pmqs@cpan.org>
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/Makefile.PL b/deb-src/libfilter-perl/libfilter-perl-1.34/Makefile.PL
new file mode 100644 (file)
index 0000000..04dd1cb
--- /dev/null
@@ -0,0 +1,153 @@
+use ExtUtils::MakeMaker;
+
+BEGIN
+{
+    die "Filters needs Perl version 5.004 or better, you have $]\n"
+       if $] < 5.004 ;
+
+    warn "Perl 5.6.0 or better is strongly recommended for Win32\n"
+       if $^O eq 'MSWin32' && $] < 5.006 ;
+}
+
+use strict;
+
+my @files = qw( filter-util.pl
+             Call/Call.pm 
+             Exec/Exec.pm 
+             decrypt/decrypt.pm decrypt/decr decrypt/encrypt
+             tee/tee.pm
+             lib/Filter/cpp.pm lib/Filter/exec.pm lib/Filter/sh.pm
+             examples/filtdef
+             examples/method/Count.pm
+             examples/method/NewSubst.pm
+             examples/method/UUdecode.pm
+             examples/method/Decompress.pm
+             examples/method/Joe2Jim.pm
+             examples/method/Subst.pm
+             examples/closure/Count.pm
+             examples/closure/NewSubst.pm
+             examples/closure/UUdecode.pm
+             examples/closure/Decompress.pm
+             examples/closure/Include.pm
+             examples/closure/Joe2Jim.pm
+             examples/closure/Subst.pm
+             examples/filtdef
+             examples/filtuu
+             t/call.t
+             t/cpp.t
+             t/decrypt.t
+             t/exec.t
+             t/order.t
+             t/sh.t
+             t/tee.t         
+           );
+             
+if ($] < 5.006001)
+ { oldWarnings(@files) }
+else
+ { newWarnings(@files) }     
+             
+
+{
+    package MY;
+
+    # Fun hack by cjwatson to get perlfilter.pod manified in section 1 with
+    # all the other perl*.pod pages.
+    sub constants {
+       my ($self) = @_;
+       $self->{MAN1PODS}->{'perlfilter.pod'} =
+           $self->catfile("\$(INST_MAN1DIR)", "perlfilter.\$(MAN1EXT)");
+       delete $self->{MAN3PODS}->{'perlfilter.pod'};
+       $self->SUPER::constants();
+    }
+}
+
+
+WriteMakefile(
+       NAME      => 'Filter',
+       VERSION   => '1.34',
+       'linkext'   => {LINKTYPE => ''},
+       'dist'    =>    {COMPRESS=>'gzip', SUFFIX=>'gz',
+                       DIST_DEFAULT => 'MyDoubleCheck tardist'},
+       ($] >= 5.005
+           ? (ABSTRACT => 'Source Filters',
+              AUTHOR   => 'Paul Marquess <pmqs@cpan.org>')
+           : ()
+       ),
+    ((ExtUtils::MakeMaker->VERSION() gt '6.30') ?
+        ('LICENSE'  => 'perl')         : ()),
+       ) ;
+
+sub MY::libscan
+{
+    my $self = shift ;
+    my $path = shift ;
+
+    return undef
+        if $path =~ /(~|\.bak)$/ || 
+           $path =~ /^\..*\.swp$/ ;
+
+    return $path;    
+}
+
+sub MY::postamble 
+{
+       '
+
+MyDoubleCheck: 
+       @echo Checking for $$^W in files
+       @perl -ne \'                                            \
+           exit 1 if /^\s*local\s*\(\s*\$$\^W\s*\)/;           \
+         \' ' . " @files || " . '                              \
+       (echo found unexpected $$^W ; exit 1)
+       @echo All is ok.
+
+' ;
+}
+
+sub oldWarnings
+{
+    local ($^I) = "" ;
+    local (@ARGV) = @_ ;
+
+    while (<>)
+    {
+       if (/^__END__/)
+       {
+           print ;
+           my $this = $ARGV ;
+           while (<>)
+           {
+               last if $ARGV ne $this ;
+               print ;
+           }
+       }
+
+       s/^(\s*)(no\s+warnings)/${1}local (\$^W) = 0; #$2/ ;
+       s/^(\s*)(use\s+warnings)/${1}local (\$^W) = 1; #$2/ ;
+       print ;
+    }
+}
+
+sub newWarnings
+{
+    local ($^I) = "" ;
+    local (@ARGV) = @_ ;
+
+    while (<>)
+    {
+       if (/^__END__/)
+       {
+           my $this = $ARGV ;
+           print ;
+           while (<>)
+           {
+               last if $ARGV ne $this ;
+               print ;
+           }
+       }
+
+       s/^(\s*)local\s*\(\$\^W\)\s*=\s*\d+\s*;\s*#\s*((no|use)\s+warnings.*)/$1$2/ ;
+       print ;
+    }
+}
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/README b/deb-src/libfilter-perl/libfilter-perl-1.34/README
new file mode 100644 (file)
index 0000000..09a5717
--- /dev/null
@@ -0,0 +1,76 @@
+                                 Source Filters
+                                  Version 1.33
+                                 1st March 2007
+        Copyright (c) 1995-2007 Paul Marquess. All rights reserved.
+         This program is free software; you can redistribute it and/or
+                 modify it under the same terms as Perl itself.
+DESCRIPTION
+-----------
+This distribution consists of a number of Source Filters.
+
+For more details see the pod documentation embedded in the .pm files.
+
+If you intend using the Filter::Call functionality, I would strongly
+recommend that you check out Damian Conway's excellent Filter::Simple
+module. Damian's module provides a much cleaner interface than
+Filter::Util::Call. Although it doesn't allow the fine control that
+Filter::Util::Call does, it should be adequate for the majority of
+applications. It's available at
+
+   http://www.cpan.org/modules/by-author/Damian_Conway/Filter-Simple.tar.gz 
+   http://www.csse.monash.edu.au/~damian/CPAN/Filter-Simple.tar.gz 
+
+PREREQUISITES
+-------------
+Before you can build the Source Filters you need to have the following
+installed on your system:
+
+    * Perl 5.004 or better. 5.6.0 or better is recommended for Win32.
+
+If your Perl is less than version 5.004_55, the "order" test harness
+will be skipped.
+
+
+BUILDING THE MODULES
+--------------------
+Assuming you have met all the prerequisites, building the modules
+should be relatively straightforward.
+
+The modules can now be built using this sequence of commands:
+    perl Makefile.PL
+    make
+    make test
+The filters have been successfully built and tested on the following
+systems (at least):
+
+       SunOS 4.1.3 (Sun C compiler & gcc 2.7.2.3)
+       Solaris 2.3 (Sun C Compiler)
+       irix 5.3        
+       irix 6.x        
+       Windows NT 4.0 (Visual C++ 5.0 and Borland C++ 5.02)
+
+GNU tr and GNU cpp must be installed somewhere on the path for the
+testsuite to pass successfully on Windows NT.
+
+INSTALLATION
+------------
+    make install
+UPDATES
+-------
+The most recent version of the Filters is always available at
+    http://www.cpan.org/modules/by-module/Filter
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/changelog b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/changelog
new file mode 100644 (file)
index 0000000..a1a3f98
--- /dev/null
@@ -0,0 +1,144 @@
+libfilter-perl (1.34-1maemo1) fremantle; urgency=low
+
+  * New Maemo packaging
+
+ -- Nito Martinez <Nito@Qindel.ES>  Wed, 14 Apr 2010 07:27:21 +0100
+
+
+llibfilter-perl (1.34-1) unstable; urgency=low
+
+  * New upstream release.
+    - Support Perl 5.10 (closes: #466751).
+  * Update copyright dates.
+
+ -- Colin Watson <cjwatson@debian.org>  Thu, 21 Feb 2008 09:18:07 +0000
+
+libfilter-perl (1.31-2) unstable; urgency=low
+
+  * Add ${shlibs:Depends} and call dh_shlibdeps.
+  * Don't ignore errors from 'make realclean' other than the Makefile not
+    existing.
+  * Use debhelper v4.
+  * Add a Homepage field.
+  * Policy version 3.7.3: no changes required.
+  * debian/watch: use dist-based URL.
+
+ -- Colin Watson <cjwatson@debian.org>  Thu, 17 Jan 2008 23:56:29 +0000
+
+libfilter-perl (1.31-1) unstable; urgency=low
+
+  * New upstream release (closes: #329543).
+  * Remove my Makefile.PL hack for Subversion from 1.29-2, which is no
+    longer necessary with current perl.
+  * Policy version 3.6.2: no changes required.
+
+ -- Colin Watson <cjwatson@debian.org>  Thu, 22 Sep 2005 09:32:09 +0100
+
+libfilter-perl (1.30-2) unstable; urgency=low
+
+  * Upgrade debian/watch to format version 2.
+  * Improve package description, based on a suggestion by Anthony DeRobertis
+    (closes: #258801).
+  * Policy version 3.6.1: no changes required.
+
+ -- Colin Watson <cjwatson@debian.org>  Sun, 11 Jul 2004 20:22:59 +0100
+
+libfilter-perl (1.30-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Colin Watson <cjwatson@debian.org>  Tue, 19 Aug 2003 00:47:33 +0100
+
+libfilter-perl (1.29-2) unstable; urgency=low
+
+  * debian/copyright: Copy Perl's licensing terms rather than referring to
+    them.
+  * debian/watch: Improve pattern to avoid downloading Filter::Trigraphs by
+    mistake.
+  * debian/control: Change section from interpreters to perl.
+  * debian/rules: Move debhelper compatibility level to debian/compat.
+    Requires debhelper 3.4.4.
+  * Makefile.PL: Add workaround from #190065 to cope with keeping the
+    package in Subversion.
+
+ -- Colin Watson <cjwatson@debian.org>  Sat, 24 May 2003 12:06:16 +0100
+
+libfilter-perl (1.29-1) unstable; urgency=low
+
+  * New upstream release (closes: #193820).
+  * Policy version 3.5.10: drop DEB_BUILD_OPTIONS=debug and support noopt.
+  * Clean up "Upstream Author(s)" in debian/copyright (lintian).
+
+ -- Colin Watson <cjwatson@debian.org>  Wed, 21 May 2003 00:22:55 +0100
+
+libfilter-perl (1.28-3) unstable; urgency=low
+
+  * Add a pointer to /usr/share/doc/perl/copyright in the copyright file
+    (closes: #157586).
+
+ -- Colin Watson <cjwatson@debian.org>  Mon, 26 Aug 2002 03:19:07 +0100
+
+libfilter-perl (1.28-2) unstable; urgency=low
+
+  * Rebuild for perl 5.8. Bumped perl build-dependency to 5.8.0-3.
+
+ -- Colin Watson <cjwatson@debian.org>  Wed, 31 Jul 2002 13:41:45 +0000
+
+libfilter-perl (1.28-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Colin Watson <cjwatson@debian.org>  Sat, 26 Jan 2002 15:22:33 +0000
+
+libfilter-perl (1.25-1) unstable; urgency=low
+
+  * New upstream release.
+  * Policy version 3.5.6, Perl policy version 1.20 (versioned
+    build-dependency on perl).
+  * Actually build-depend on perl 5.6.1 so that new warnings are used.
+  * Add evil hack to Makefile.PL to install perlfilter.pod in section 1p.
+
+ -- Colin Watson <cjwatson@debian.org>  Thu,  4 Oct 2001 01:06:04 +0100
+
+libfilter-perl (1.23-1) unstable; urgency=low
+
+  * New upstream release.
+  * Build-depend on debhelper (>= 3.0.18), in accordance with version 1.19
+    of the Perl policy.
+
+ -- Colin Watson <cjwatson@debian.org>  Sat, 19 May 2001 15:31:52 +0100
+
+libfilter-perl (1.22-1) unstable; urgency=low
+
+  * New upstream release.
+  * Updated policy version to 3.5.2.
+  * Install our perlfilter documentation; vendor packages now put podfiles
+    in a different place to core packages, and while perl-doc installs
+    perlfilter(1) we happen to install perlfilter(3pm). I've filed a bug
+    against perl-doc asking for the perlfilter documentation to be removed
+    from there, as otherwise man will show perlfilter(1) in preference.
+
+ -- Colin Watson <cjwatson@debian.org>  Sun,  4 Mar 2001 17:59:08 +0000
+
+libfilter-perl (1.20-2) unstable; urgency=low
+
+  * Update to new Perl policy.
+  * Suggest libcompress-zlib-perl for the benefit of the filtdef example.
+
+ -- Colin Watson <cjwatson@debian.org>  Thu, 15 Feb 2001 12:01:29 +0000
+
+libfilter-perl (1.20-1) unstable; urgency=low
+
+  * Uploaded to Debian (closes: #85155, #85343).
+  * New maintainer address.
+  * New upstream release.
+  * Updated policy version to 3.5.0.
+  * Fixed debian/watch.
+
+ -- Colin Watson <cjwatson@debian.org>  Fri,  9 Feb 2001 21:26:49 +0000
+
+libfilter-perl (1.19-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Colin Watson <cjw44@flatline.org.uk>  Wed, 27 Dec 2000 21:42:32 +0000
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/compat b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/compat
new file mode 100644 (file)
index 0000000..b8626c4
--- /dev/null
@@ -0,0 +1 @@
+4
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/control b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/control
new file mode 100644 (file)
index 0000000..1f59d10
--- /dev/null
@@ -0,0 +1,25 @@
+Source: libfilter-perl
+Section: perl
+Priority: optional
+Maintainer: Colin Watson <cjwatson@debian.org>
+Build-Depends: debhelper (>= 4.0.0), perl (>= 5.8.0-3)
+Standards-Version: 3.7.3
+Homepage: http://www.cpan.org/modules/by-module/Filter/
+
+Package: libfilter-perl
+Architecture: any
+Depends: ${shlibs:Depends}, ${perl:Depends}
+Suggests: libcompress-zlib-perl
+Description: Perl source filters
+ Source filters alter the program text of a module before Perl sees it, much
+ as a C preprocessor alters the source text of a C program before the
+ compiler sees it.
+ .
+ This package contains a number of source filters, including:
+ .
+   exec and sh: pipe the source file through an external command
+   cpp: pipe the source file through the C preprocessor
+   decrypt: example of simple (though weak!) source obfuscation
+   tee: copy filtered source to a file (debugging aid)
+ .
+ A substantial amount of documentation and examples is also included.
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/copyright b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/copyright
new file mode 100644 (file)
index 0000000..99bbf3f
--- /dev/null
@@ -0,0 +1,27 @@
+This package was debianized by Colin Watson <cjwatson@debian.org> on
+Wed, 27 Dec 2000 21:19:47 +0000.
+
+It was downloaded from http://www.cpan.org/modules/by-module/Filter/
+
+Upstream Author: Paul Marquess <Paul.Marquess@btinternet.com>
+
+Copyright:
+
+Copyright (c) 1995-2007 Paul Marquess. All rights reserved.
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+Perl's licensing terms at the time of writing are as follows:
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of either:
+
+    a) the GNU General Public License as published by the Free Software
+       Foundation; either version 1, or (at your option) any later
+       version, or
+
+    b) the "Artistic License" which comes with Perl.
+
+    On Debian GNU/Linux systems, the complete text of the GNU General
+    Public License can be found in `/usr/share/common-licenses/GPL' and
+    the Artistic Licence in `/usr/share/common-licenses/Artistic'.
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/docs b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/docs
new file mode 100644 (file)
index 0000000..e845566
--- /dev/null
@@ -0,0 +1 @@
+README
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/examples b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/examples
new file mode 100644 (file)
index 0000000..e39721e
--- /dev/null
@@ -0,0 +1 @@
+examples/*
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/rules b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/rules
new file mode 100755 (executable)
index 0000000..16c48c5
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+tmp       = $(CURDIR)/debian/libfilter-perl
+config    = INSTALLDIRS=vendor INSTALLMAN3DIR=/usr/share/man/man3
+vendorarch = `perl -MConfig -e 'print $$Config{vendorarch}'`
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # Add here commands to configure the package.
+       perl Makefile.PL $(config)
+
+       touch configure-stamp
+
+build: configure build-stamp
+build-stamp:
+       dh_testdir
+
+       # Add here commands to compile the package.
+ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       $(MAKE) OPTIMIZE="-O2 -g -Wall"
+else
+       $(MAKE) OPTIMIZE="-g -Wall"
+endif
+
+       touch build-stamp
+
+clean: configure
+       dh_testdir
+       dh_testroot
+
+       # Add here commands to clean up after the build process.
+       [ ! -f Makefile ] || $(MAKE) realclean
+       rm -f Try.pm    # for 'make test'
+
+       dh_clean build-stamp configure-stamp
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       # Add here commands to install the package into debian/tmp.
+       $(MAKE) install PREFIX=$(tmp)/usr
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installdocs
+       dh_installexamples
+       dh_installchangelogs Changes
+       dh_strip
+       dh_compress
+       dh_fixperms
+       dh_installdeb
+       dh_perl
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/debian/watch b/deb-src/libfilter-perl/libfilter-perl-1.34/debian/watch
new file mode 100644 (file)
index 0000000..132eef8
--- /dev/null
@@ -0,0 +1,2 @@
+version=3
+http://search.cpan.org/dist/Filter/   .*/Filter-v?(\d[\d_.]+)\.(?:tar(?:\.gz|\.bz2)?|tgz|zip) debian uupdate
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/Makefile.PL b/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/Makefile.PL
new file mode 100755 (executable)
index 0000000..49988e2
--- /dev/null
@@ -0,0 +1,12 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+       NAME      => 'Filter::decrypt',
+       VERSION_FROM   => 'decrypt.pm',
+
+       # The line below disables both the dynamic link test and the
+       # test for DEBUGGING.
+       # It is only enabled here to allow the decrypt test harness
+       # to run without having to build statically.
+       DEFINE    => "-DBYPASS",
+);
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decr b/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decr
new file mode 100644 (file)
index 0000000..592414e
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/local/bin/perl
+
+# This script will decrypt a Perl script that has been encrypted using the
+# "encrypt" script. It cannot decrypt any other kind of encrypted Perl script.
+#
+# Usage is decr file...
+#
+
+use strict;
+use warnings;
+
+use vars qw($XOR $BLOCKSIZE $HEADERSIZE $CRYPT_MAGIC_1 $CRYPT_MAGIC_2
+            $size $mode $line $Fingerprint $file $block $sharp_bang $f
+           ) ;   
+$XOR             = 'Perl' ;
+$BLOCKSIZE       = length $XOR ;
+$HEADERSIZE      = 2 ;
+$CRYPT_MAGIC_1   = 0xff ;
+$CRYPT_MAGIC_2   = 0x00 ;
+my $Version         = 1 ;
+my $module_name     = 'Filter::decrypt' ;
+
+my $Fingerprint     = pack ("C*", $CRYPT_MAGIC_1, $CRYPT_MAGIC_2) ;
+
+die "Usage: decrypt file...\n"
+  unless @ARGV ;
+
+
+# Loop through each file in turn.
+foreach $file (@ARGV)
+{
+    if (! -f $file)
+    {
+        print "Skipping directory $file\n" if -d $file ;
+        #print "Skipping strange file $file\n" if ! -d $file ;
+        next ;
+    }
+
+    open (F, "<$file") || die "Cannot open $file: $!\n" ;
+
+    # skip the #! line
+    $a = <F> ;
+    if ($a =~ /^#!/)
+    {
+        $sharp_bang = $a ;
+        $a = <F> ;
+    }
+
+    # skip "use decrypt;" line
+    die "No use $module_name in $file\n"
+        unless $a =~ /use\s+$module_name\s*;/ ;
+
+    read(F, $f, length($Fingerprint)) || die "Cannot read from $file: $!\n" ;
+    (print "skipping file '$file': not encrypted\n"), next
+        unless $f eq $Fingerprint ;
+
+    print "decrypting $file to $file.pd\n" ;
+    open (O, ">${file}.pd") || die "Cannot open ${file}.pd: $!\n" ;
+    print O $sharp_bang if $sharp_bang ;
+    while ($size = read(F, $block, $BLOCKSIZE) )
+    {
+        print O ($block ^ substr($XOR, 0, $size)) ;
+    }
+
+
+    close F ;
+    close O ;
+
+}
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decrypt.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decrypt.pm
new file mode 100644 (file)
index 0000000..c0d1acb
--- /dev/null
@@ -0,0 +1,115 @@
+package Filter::decrypt ;
+
+require 5.002 ;
+require DynaLoader;
+use strict;
+use warnings;
+use vars qw(@ISA $VERSION);
+@ISA = qw(DynaLoader);
+$VERSION = "1.05" ;
+
+bootstrap Filter::decrypt ;
+1;
+__END__
+
+=head1 NAME
+
+Filter::decrypt - template for a decrypt source filter
+
+=head1 SYNOPSIS
+
+    use Filter::decrypt ;
+
+=head1 DESCRIPTION
+
+This is a sample decrypting source filter.
+
+Although this is a fully functional source filter and it does implement
+a I<very> simple decrypt algorithm, it is I<not> intended to be used as
+it is supplied. Consider it to be a template which you can combine with
+a proper decryption algorithm to develop your own decryption filter.
+
+=head1 WARNING
+
+It is important to note that a decryption filter can I<never> provide
+complete security against attack. At some point the parser within Perl
+needs to be able to scan the original decrypted source. That means that
+at some stage fragments of the source will exist in a memory buffer. 
+
+Also, with the introduction of the Perl Compiler backend modules, and
+the B::Deparse module in particular, using a Source Filter to hide source
+code is becoming an increasingly futile exercise.
+
+The best you can hope to achieve by decrypting your Perl source using a
+source filter is to make it unavailable to the casual user.
+
+Given that proviso, there are a number of things you can do to make
+life more difficult for the prospective cracker.
+
+=over 5
+
+=item 1.
+
+Strip the Perl binary to remove all symbols.
+
+=item 2.
+
+Build the decrypt extension using static linking. If the extension is
+provided as a dynamic module, there is nothing to stop someone from
+linking it at run time with a modified Perl binary.
+
+=item 3.
+
+Do not build Perl with C<-DDEBUGGING>. If you do then your source can
+be retrieved with the C<-Dp> command line option. 
+
+The sample filter contains logic to detect the C<DEBUGGING> option.
+
+=item 4.
+
+Do not build Perl with C debugging support enabled.
+
+=item 5.
+
+Do not implement the decryption filter as a sub-process (like the cpp
+source filter). It is possible to peek into the pipe that connects to
+the sub-process.
+
+=item 6.
+
+Check that the Perl Compiler isn't being used. 
+
+There is code in the BOOT: section of decrypt.xs that shows how to detect
+the presence of the Compiler. Make sure you include it in your module.
+
+Assuming you haven't taken any steps to spot when the compiler is in
+use and you have an encrypted Perl script called "myscript.pl", you can
+get access the source code inside it using the perl Compiler backend,
+like this
+
+    perl -MO=Deparse myscript.pl
+
+Note that even if you have included the BOOT: test, it is still
+possible to use the Deparse module to get the source code for individual
+subroutines.
+
+=item 7.
+
+Do not use the decrypt filter as-is. The algorithm used in this filter
+has been purposefully left simple.
+
+=back
+
+If you feel that the source filtering mechanism is not secure enough
+you could try using the unexec/undump method. See the Perl FAQ for
+further details.
+
+=head1 AUTHOR
+
+Paul Marquess 
+
+=head1 DATE
+
+19th December 1995
+
+=cut
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decrypt.xs b/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/decrypt.xs
new file mode 100644 (file)
index 0000000..61113be
--- /dev/null
@@ -0,0 +1,321 @@
+/* 
+ * Filename : decrypt.xs
+ * 
+ * Author   : Paul Marquess 
+ * Date     : 20th July 2000
+ * Version  : 1.05
+ *
+ */
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "../Call/ppport.h"
+
+#ifdef FDEBUG
+static int fdebug = 0;
+#endif
+
+/* constants specific to the encryption format */
+#define CRYPT_MAGIC_1  0xff
+#define CRYPT_MAGIC_2  0x00
+
+#define HEADERSIZE     2
+#define BLOCKSIZE      4
+
+
+#define SET_LEN(sv,len) \
+        do { SvPVX(sv)[len] = '\0'; SvCUR_set(sv, len); } while (0)
+
+
+static unsigned XOR [BLOCKSIZE] = {'P', 'e', 'r', 'l' } ;
+
+
+/* Internal defines */
+#ifdef PERL_FILTER_EXISTS
+#  define CORE_FILTER_COUNT \
+    (PL_parser && PL_parser->rsfp_filters ? av_len(PL_parser->rsfp_filters) : 0)
+#else
+#  define CORE_FILTER_COUNT \
+    (PL_rsfp_filters ? av_len(PL_rsfp_filters) : 0)
+#endif
+
+#define FILTER_COUNT(s)                IoPAGE(s)
+#define FILTER_LINE_NO(s)      IoLINES(s)
+#define FIRST_TIME(s)          IoLINES_LEFT(s)
+
+#define ENCRYPT_GV(s)          IoTOP_GV(s)
+#define ENCRYPT_SV(s)          ((SV*) ENCRYPT_GV(s))
+#define ENCRYPT_BUFFER(s)      SvPVX(ENCRYPT_SV(s))
+#define CLEAR_ENCRYPT_SV(s)    SvCUR_set(ENCRYPT_SV(s), 0)
+
+#define DECRYPT_SV(s)          s
+#define DECRYPT_BUFFER(s)      SvPVX(DECRYPT_SV(s))
+#define CLEAR_DECRYPT_SV(s)    SvCUR_set(DECRYPT_SV(s), 0)
+#define DECRYPT_BUFFER_LEN(s)  SvCUR(DECRYPT_SV(s))
+#define DECRYPT_OFFSET(s)      IoPAGE_LEN(s)
+#define SET_DECRYPT_BUFFER_LEN(s,n)    SvCUR_set(DECRYPT_SV(s), n)
+
+static unsigned
+Decrypt(SV *in_sv, SV *out_sv)
+{
+       /* Here is where the actual decryption takes place */
+
+       unsigned char * in_buffer  = (unsigned char *) SvPVX(in_sv) ;
+       unsigned char * out_buffer ;
+       unsigned size = SvCUR(in_sv) ;
+       unsigned index = size ;
+       int i ;
+
+       /* make certain that the output buffer is big enough            */
+       /* as the output from the decryption can never be larger than   */
+       /* the input buffer, make it that size                          */
+       SvGROW(out_sv, size) ;
+       out_buffer = (unsigned char *) SvPVX(out_sv) ;
+
+        /* XOR */
+        for (i = 0 ; i < size ; ++i) 
+            out_buffer[i] = (unsigned char)( XOR[i] ^ in_buffer[i] ) ;
+
+       /* input has been consumed, so set length to 0 */
+       SET_LEN(in_sv, 0) ;
+
+       /* set decrypt buffer length */
+       SET_LEN(out_sv, index) ;
+
+       /* return the size of the decrypt buffer */
+       return (index) ;
+}
+
+static int
+ReadBlock(int idx, SV *sv, unsigned size)
+{   /* read *exactly* size bytes from the next filter */
+    int i = size;
+    while (1) {
+        int n = FILTER_READ(idx, sv, i) ;
+        if (n <= 0 && i==size)  /* eof/error when nothing read so far */
+            return n ;
+        if (n <= 0)             /* eof/error when something already read */
+            return size - i;
+        if (n == i)
+            return size ;
+        i -= n ;
+    }
+}
+
+static void
+preDecrypt(int idx)
+{
+    /* If the encrypted data starts with a header or needs to do some
+       initialisation it can be done here 
+
+       In this case the encrypted data has to start with a fingerprint,
+       so that is checked.
+    */
+
+    SV * sv = FILTER_DATA(idx) ;
+    unsigned char * buffer ;
+
+
+    /* read the header */
+    if (ReadBlock(idx+1, sv, HEADERSIZE) != HEADERSIZE)
+       croak("truncated file") ;
+
+    buffer = (unsigned char *) SvPVX(sv) ;
+
+    /* check for fingerprint of encrypted data */
+    if (buffer[0] != CRYPT_MAGIC_1 || buffer[1] != CRYPT_MAGIC_2) 
+            croak( "bad encryption format" );
+}
+
+static void
+postDecrypt()
+{
+}
+
+static I32
+filter_decrypt(pTHX_ int idx, SV *buf_sv, int maxlen)
+{
+    SV   *my_sv = FILTER_DATA(idx);
+    char *nl = "\n";
+    char *p;
+    char *out_ptr;
+    int n;
+
+    /* check if this is the first time through */
+    if (FIRST_TIME(my_sv)) {
+
+       /* Mild paranoia mode - make sure that no extra filters have    */
+       /* been applied on the same line as the use Filter::decrypt     */
+        if (CORE_FILTER_COUNT > FILTER_COUNT(my_sv) )
+           croak("too many filters") ; 
+
+       /* As this is the first time through, so deal with any          */
+       /* initialisation required                                      */
+        preDecrypt(idx) ;
+
+       FIRST_TIME(my_sv) = FALSE ;
+        SET_LEN(DECRYPT_SV(my_sv), 0) ;
+        SET_LEN(ENCRYPT_SV(my_sv), 0) ;
+        DECRYPT_OFFSET(my_sv)    = 0 ;
+    }
+
+#ifdef FDEBUG
+    if (fdebug)
+       warn("**** In filter_decrypt - maxlen = %d, len buf = %d idx = %d\n", 
+               maxlen, SvCUR(buf_sv), idx ) ;
+#endif
+
+    while (1) {
+
+       /* anything left from last time */
+       if ((n = SvCUR(DECRYPT_SV(my_sv)))) {
+
+           out_ptr = SvPVX(DECRYPT_SV(my_sv)) + DECRYPT_OFFSET(my_sv) ;
+
+           if (maxlen) { 
+               /* want a block */ 
+#ifdef FDEBUG
+               if (fdebug)
+                   warn("BLOCK(%d): size = %d, maxlen = %d\n", 
+                       idx, n, maxlen) ;
+#endif
+
+               sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
+               if(n <= maxlen) {
+                   DECRYPT_OFFSET(my_sv) = 0 ;
+                   SET_LEN(DECRYPT_SV(my_sv), 0) ;
+               }
+               else {
+                   DECRYPT_OFFSET(my_sv) += maxlen ;
+                   SvCUR_set(DECRYPT_SV(my_sv), n - maxlen) ;
+               }
+               return SvCUR(buf_sv);
+           }
+           else {
+               /* want lines */
+                if ((p = ninstr(out_ptr, out_ptr + n, nl, nl + 1))) {
+
+                   sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);
+
+                   n = n - (p - out_ptr + 1);
+                   DECRYPT_OFFSET(my_sv) += (p - out_ptr + 1) ;
+                   SvCUR_set(DECRYPT_SV(my_sv), n) ;
+#ifdef FDEBUG 
+                   if (fdebug)
+                       warn("recycle %d - leaving %d, returning %d [%.999s]", 
+                               idx, n, SvCUR(buf_sv), SvPVX(buf_sv)) ;
+#endif
+
+                   return SvCUR(buf_sv);
+               }
+               else /* no EOL, so append the complete buffer */
+                   sv_catpvn(buf_sv, out_ptr, n) ;
+           }
+           
+       }
+
+
+       SET_LEN(DECRYPT_SV(my_sv), 0) ;
+        DECRYPT_OFFSET(my_sv) = 0 ;
+
+       /* read from the file into the encrypt buffer */
+       if ( (n = ReadBlock(idx+1, ENCRYPT_SV(my_sv), BLOCKSIZE)) <= 0)
+       {
+           /* Either EOF or an error */
+
+#ifdef FDEBUG
+           if (fdebug)
+               warn ("filter_read %d returned %d , returning %d\n", idx, n,
+                   (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n);
+#endif
+
+           /* If the decrypt code needs to tidy up on EOF/error, 
+               now is the time  - here is a hook */
+           postDecrypt() ; 
+
+           filter_del(filter_decrypt);  
+
+            /* If error, return the code */
+            if (n < 0)
+                return n ;
+
+           /* return what we have so far else signal eof */
+           return (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n;
+       }
+
+#ifdef FDEBUG
+       if (fdebug)
+           warn("  filter_decrypt(%d): sub-filter returned %d: '%.999s'",
+               idx, n, SvPV(my_sv,PL_na));
+#endif
+
+       /* Now decrypt a block */
+       n = Decrypt(ENCRYPT_SV(my_sv), DECRYPT_SV(my_sv)) ;
+
+#ifdef FDEBUG 
+       if (fdebug) 
+           warn("Decrypt (%d) returned %d [%.999s]\n", idx, n, SvPVX(DECRYPT_SV(my_sv)) ) ;
+#endif 
+
+    }
+}
+
+
+MODULE = Filter::decrypt       PACKAGE = Filter::decrypt
+
+PROTOTYPES:    DISABLE
+
+BOOT:
+    /* Check for the presence of the Perl Compiler */
+    if (gv_stashpvn("B", 1, FALSE))
+        croak("Aborting, Compiler detected") ;
+#ifndef BYPASS
+    /* Don't run if this module is dynamically linked */
+    if (!isALPHA(SvPV(GvSV(CvFILEGV(cv)), PL_na)[0]))
+       croak("module is dynamically linked. Recompile as a static module") ;
+#ifdef DEBUGGING
+       /* Don't run if compiled with DEBUGGING */
+       croak("recompile without -DDEBUGGING") ;
+#endif
+        
+       /* Double check that DEBUGGING hasn't been enabled */
+       if (PL_debug)
+           croak("debugging flags detected") ;
+#endif
+
+
+void
+import(module)
+    SV *       module
+    PPCODE:
+    {
+
+        SV * sv = newSV(BLOCKSIZE) ;
+
+       /* make sure the Perl debugger isn't enabled */
+       if( PL_perldb )
+           croak("debugger disabled") ;
+
+        filter_add(filter_decrypt, sv) ;
+       FIRST_TIME(sv) = TRUE ;
+
+        ENCRYPT_GV(sv) = (GV*) newSV(BLOCKSIZE) ;
+        (void)SvPOK_only(DECRYPT_SV(sv));
+        (void)SvPOK_only(ENCRYPT_SV(sv));
+        SET_LEN(DECRYPT_SV(sv), 0) ;
+        SET_LEN(ENCRYPT_SV(sv), 0) ;
+
+
+        /* remember how many filters are enabled */
+        FILTER_COUNT(sv) = CORE_FILTER_COUNT ;
+       /* and the line number */
+       FILTER_LINE_NO(sv) = PL_curcop->cop_line ;
+
+    }
+
+void
+unimport(...)
+    PPCODE:
+    /* filter_del(filter_decrypt); */
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/encrypt b/deb-src/libfilter-perl/libfilter-perl-1.34/decrypt/encrypt
new file mode 100755 (executable)
index 0000000..314612a
--- /dev/null
@@ -0,0 +1,71 @@
+
+require 5.002 ;
+
+use strict;
+use warnings;
+
+use vars qw($XOR $BLOCKSIZE $HEADERSIZE $CRYPT_MAGIC_1 $CRYPT_MAGIC_2
+           $size $mode $line $Fingerprint $file $block
+          ) ;
+
+$XOR           = 'Perl' ;
+$BLOCKSIZE       = length $XOR ;
+$HEADERSIZE      = 2 ;
+$CRYPT_MAGIC_1   = 0xff ;
+$CRYPT_MAGIC_2   = 0x00 ;
+
+$Fingerprint     = pack ("C*", $CRYPT_MAGIC_1, $CRYPT_MAGIC_2) ;
+
+die "Usage: encrypt file...\n"
+  unless @ARGV ;
+
+# Loop throught each file in turn.
+foreach $file (@ARGV)
+{
+
+    if (! -T $file)
+    {
+       print "Skipping directory $file\n" if -d $file ;
+       print "Skipping non-text $file\n" if ! -d $file ;
+       next ;
+    }
+
+    open (F, "<$file") or die "Cannot open $file: $!\n" ;
+    open (O, ">${file}.pe") or die "Cannot open ${file}.pe: $!\n" ;
+    binmode O;
+
+    # Get the mode
+    $mode = (stat F)[2] ;
+
+    # Check for "#!perl" line
+    $line = <F> ;
+
+    if ( $line =~ /^#!/ ) 
+      { print O $line }
+    else
+      { seek F, 0, 0 }
+    
+    print O "use Filter::decrypt ;\n" ;
+    print O $Fingerprint ;
+
+
+    $block = '';
+    while ($size = read(F, $block, $BLOCKSIZE) )
+    {
+        print O ($block ^ substr($XOR, 0, length $block)) ;
+    }
+
+    close F ;
+    close O ;
+
+    unlink ($file) 
+       or die "Could not remove '$file': $!\n" ;
+
+    rename ("${file}.pe", $file) 
+       or die "Could not rename $file.pe to $file: $!\n" ;
+
+    chmod $mode, $file unless $^O eq 'MSWin32' ;
+
+    print "encrypted $file\n" ;
+}
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Count.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Count.pm
new file mode 100644 (file)
index 0000000..2ed8f44
--- /dev/null
@@ -0,0 +1,32 @@
+package Count ;
+use Filter::Util::Call ;
+
+use strict ;
+use warnings ;
+sub import
+{
+    my ($self) = @_ ;
+    my ($count) = 0 ;
+    filter_add(
+       sub 
+       {
+           my ($status) ;
+        
+           if (($status = filter_read()) > 0 ) {
+                   s/Joe/Jim/g ;
+                   ++ $count ;
+           }
+           elsif ($count >= 0) { # EOF
+               $_ = "print q[Made $count substitutions\n] ;" ;
+               $status = 1 ;
+               $count = -1 ;
+               }
+           $status ;
+       }) 
+}
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Decompress.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Decompress.pm
new file mode 100644 (file)
index 0000000..b086324
--- /dev/null
@@ -0,0 +1,33 @@
+package Filter::Decompress ;
+use Filter::Util::Call ;
+use Compress::Zlib ;
+use Carp ;
+
+use strict ;
+use warnings ;
+
+my $VERSION = '1.01' ;
+
+sub import
+{
+    my ($self) = @_ ;
+
+    # Initialise an inflation stream.
+    my $x = inflateInit() 
+        or croak "Internal Error" ;
+    filter_add(
+        sub 
+        { 
+            my ($status, $err) ;
+        
+            if (($status = filter_read()) >0) {
+                ($_, $err) = $x->inflate($_) ;
+                return -1 unless $err == Z_OK or $err == Z_STREAM_END ;
+            }
+            $status ;
+        })
+}
+
+1 ;
+__END__
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Include.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Include.pm
new file mode 100644 (file)
index 0000000..3d27888
--- /dev/null
@@ -0,0 +1,38 @@
+package Include ;
+use Filter::Util::Call ;
+use IO::File ;
+use Carp ;
+sub import
+{
+    my ($self) = shift ;
+    my ($filename) = shift ;
+    my $fh = new IO::File "<$filename" 
+       or croak "Cannot open file '$filename': $!" ;
+
+    my $first_time = 1 ;
+    my ($orig_filename, $orig_line) = (caller)[1,2] ;
+    ++ $orig_line ;
+
+    filter_add(
+       sub 
+       {
+           $_ = <$fh> ;
+
+           if ($first_time) {
+               $_ = "#line 1 $filename\n$_"  ;
+               $first_time = 0 ;
+           }
+
+           if ($fh->eof) {
+               $fh->close ;
+               $_ .= "#line $orig_line $orig_filename\n" ;
+               filter_del() ;
+           }
+           1 ;
+       }) 
+}
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Joe2Jim.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Joe2Jim.pm
new file mode 100644 (file)
index 0000000..acdaa9a
--- /dev/null
@@ -0,0 +1,23 @@
+package Joe2Jim ;
+use Filter::Util::Call ;
+
+use strict ;
+use warnings ;
+sub import
+{
+    my($type) = @_ ;
+    filter_add(
+        sub 
+        {
+            my($status) ;
+            s/Joe/Jim/g
+                if ($status = filter_read()) > 0 ;
+            $status ;
+        })
+}
+
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/NewSubst.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/NewSubst.pm
new file mode 100644 (file)
index 0000000..4144661
--- /dev/null
@@ -0,0 +1,37 @@
+package NewSubst ;
+use Filter::Util::Call ;
+use Carp ;
+
+use strict ;
+use warnings ;
+sub import
+{
+    my ($self, $start, $stop, $from, $to) = @_ ;
+    my ($found) = 0 ;
+    croak("usage: use Subst qw(start stop from to)")
+        unless @_ == 5 ;
+    filter_add( 
+        sub 
+        {
+            my ($status) ;
+         
+            if (($status = filter_read()) > 0) {
+         
+                $found = 1
+                    if $found == 0 and /$start/ ;
+         
+                if ($found) {
+                    s/$from/$to/ ;
+                    filter_del() if /$stop/ ;
+                }
+         
+            }
+            $status ;
+        } )
+
+}
+1 ;
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Subst.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/Subst.pm
new file mode 100644 (file)
index 0000000..0754fe3
--- /dev/null
@@ -0,0 +1,24 @@
+package Subst ;
+use Filter::Util::Call ;
+use Carp ;
+
+use strict ;
+use warnings ;
+sub import
+{
+    croak("usage: use Subst qw(from to)")
+        unless @_ == 3 ;
+    my ($self, $from, $to) = @_ ;
+    filter_add(
+        sub 
+        {
+            my ($status) ;
+            s/$from/$to/
+                if ($status = filter_read()) > 0 ;
+            $status ;
+        })
+}
+1 ;
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/UUdecode.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/closure/UUdecode.pm
new file mode 100644 (file)
index 0000000..b74017b
--- /dev/null
@@ -0,0 +1,52 @@
+
+package Filter::UUdecode ;
+
+use Filter::Util::Call ;
+
+use strict ;
+use warnings ;
+
+my $VERSION = '1.00' ;
+
+sub import
+{
+    my($self) = @_ ;
+    my ($count) = 0 ;
+
+    filter_add( 
+        sub 
+        {
+            my ($status) ;
+        
+            while (1) {
+        
+               return $status 
+                   if ($status = filter_read() ) <= 0;
+        
+               chomp ;
+               ++ $count ;
+        
+               # Skip the begin line (if it is there)
+               ($_ = ''), next if $count == 1 and /^begin/ ;
+        
+               # is this the last line?
+               if ($_ eq " " or length $_ <= 1) {
+                   $_ = '' ;
+                   # If there is an end line, skip it too
+                    return $status
+                       if ($status = filter_read() ) <= 0 ;
+                    $_ = "\n" if /^end/ ;
+                   filter_del() ;
+                   return 1 ;
+               }
+        
+               # uudecode the line
+               $_ = unpack("u", $_) ;
+        
+               # return the uudecoded data
+               return $status ;
+            }
+        })
+        
+}
+1 ;
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/filtdef b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/filtdef
new file mode 100755 (executable)
index 0000000..5128ec9
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+
+use strict ;
+use warnings ;
+
+my ($file, $output, $status) ;
+
+use Compress::Zlib ;
+
+die "Usage: mkdef file\n"
+    unless @ARGV == 1;
+
+foreach $file (@ARGV) 
+{
+    open (F, "<$file") or die "Cannot open $file: $!\n" ;
+    my $x = deflateInit()
+       or die "Cannot create a deflation stream\n" ;
+
+    print "use Filter::Decompress;\n" ;
+    while (<F>)
+    {
+        ($output, $status) = $x->deflate($_) ;
+    
+        $status == Z_OK
+            or die "deflation failed\n" ;
+    
+        print $output ;
+    }
+    
+    ($output, $status) = $x->flush() ;
+    
+    $status == Z_OK
+        or die "deflation failed\n" ;
+    
+    print $output ;
+    close F ;
+}
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/filtuu b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/filtuu
new file mode 100755 (executable)
index 0000000..dfebfc5
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/perl
+
+print "use Filter::UUdecode ;\n" ;
+while (<>) {
+    print pack("u", $_) ;
+}
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Count.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Count.pm
new file mode 100644 (file)
index 0000000..c4491a6
--- /dev/null
@@ -0,0 +1,34 @@
+package Count ;
+use Filter::Util::Call ;
+use strict ;
+use warnings ;
+
+sub filter
+{
+    my ($self) = @_ ;
+    my ($status) ;
+    if (($status = filter_read()) > 0 ) {
+        s/Joe/Jim/g ;
+        ++ $$self ;
+    }
+    elsif ($$self >= 0) { # EOF
+        $_ = "print q[Made ${$self} substitutions\n] ;" ;
+        $status = 1 ;
+       $$self = -1 ;
+    }
+    $status ;
+}
+sub import
+{
+    my ($self) = @_ ;
+    my ($count) = 0 ;
+    filter_add(\$count) ;
+}
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Decompress.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Decompress.pm
new file mode 100644 (file)
index 0000000..a658853
--- /dev/null
@@ -0,0 +1,36 @@
+package Filter::Decompress ;
+use Filter::Util::Call ;
+use Compress::Zlib ;
+use Carp ;
+
+use strict ;
+use warnings ;
+
+my $VERSION = '1.01' ;
+
+sub filter 
+{ 
+    my ($self) = @_ ;
+    my ($status) ;
+    my ($inf) = $$self ;
+
+    if (($status = filter_read()) >0) {
+        ($_, $err) = $inf->inflate($_) ;
+        return -1 unless $err == Z_OK or $err == Z_STREAM_END ;
+    }
+    $status ;
+}
+
+sub import
+{
+    my ($self) = @_ ;
+
+    # Initialise an inflation stream.
+    my $x = inflateInit() 
+        or croak "Internal Error" ;
+    filter_add(\$x) ;
+}
+
+1 ;
+__END__
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Joe2Jim.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Joe2Jim.pm
new file mode 100644 (file)
index 0000000..901bef5
--- /dev/null
@@ -0,0 +1,26 @@
+package Joe2Jim ;
+use Filter::Util::Call ;
+
+use strict ;
+use warnings ;
+sub import
+{
+    my($type) = @_ ;
+    filter_add(bless []) ;
+}
+sub filter
+{
+    my($self) = @_ ;
+    my($status) ;
+    s/Joe/Jim/g
+        if ($status = filter_read()) > 0 ;
+    $status ;
+}
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/NewSubst.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/NewSubst.pm
new file mode 100644 (file)
index 0000000..8eae2e8
--- /dev/null
@@ -0,0 +1,43 @@
+package NewSubst ;
+use Filter::Util::Call ;
+use Carp ;
+use strict ;
+use warnings ;
+
+sub filter
+{
+    my ($self) = @_ ;
+    my ($status) ;
+    if (($status = filter_read()) > 0) {
+        $self->{Found} = 1
+            if $self->{Found} == 0 and  /$self->{Start}/ ;
+        if ($self->{Found}) {
+            s/$self->{From}/$self->{To}/ ;
+            filter_del() if /$self->{Stop}/ ;
+        }
+    }
+    $status ;
+}
+sub import
+{
+    my ($self, @args) = @_ ;
+    croak("usage: use Subst qw(start stop from to)")
+        unless @args == 4 ;
+    filter_add( { Start => $args[0],
+                  Stop  => $args[1],
+                  From  => $args[2],
+                  To    => $args[3],
+                  Found => 0 }
+              ) ;
+}
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Subst.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/Subst.pm
new file mode 100644 (file)
index 0000000..3d10c0b
--- /dev/null
@@ -0,0 +1,30 @@
+package Subst ;
+use Filter::Util::Call ;
+use Carp ;
+
+use strict ;
+use warnings ;
+sub filter
+{
+    my ($self) = @_ ;
+    my ($status) ;
+    my ($from) = $self->[0] ;
+    my ($to) = $self->[1] ;
+    s/$from/$to/
+        if ($status = filter_read()) > 0 ;
+    $status ;
+}
+sub import
+{
+    my ($self, @args) = @_ ;
+    croak("usage: use Subst qw(from to)")
+        unless @args == 2 ;
+    filter_add([ @args ]) ;
+}
+1 ;
+
diff --git a/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/UUdecode.pm b/deb-src/libfilter-perl/libfilter-perl-1.34/examples/method/UUdecode.pm
new file mode 100644 (file)
index 0000000..