#!/usr/bin/perl use lib q#../lib#; use strict; our $VERSION=do{my @r=(q$Revision: 1.2 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; require RCSFormat; require IO::File; $/ = undef; my $filename = shift @ARGV; my $rcs = new RCSFormat; my $in = new IO::File $filename, 'r' or die "$0: $filename: $!"; binmode $in; $rcs->parse_text (scalar <$in>); close $in; my %outputed; $filename =~ s/,v$//g; output_file ($rcs, revision => $rcs->{admin}->{head}, filename_base => $filename); sub output_file ($%) { my ($rcs, %opt) = @_; my $date = $rcs->{delta}->{$opt{revision}}->{date}; $date =~ s/^(\d\d)\./19$1/; $date =~ tr/.//d; my $filename = $opt{filename_base} . '.' . $date; if (-e $filename) { my $i = 1; $i++ while -e $filename . '.' . $i; $filename .= '.' . $i; } STDERR->print ("$0: Writing $opt{revision} as $filename...\n"); my $text; if ($opt{previous_text}) { $text = patch_rcs_diff ($opt{previous_text} => \$rcs->{deltatext}->{$opt{revision}}->{text}); } else { $text = $rcs->{deltatext}->{$opt{revision}}->{text}; } my $file = new IO::File $filename, 'w' or die "$0: $filename: $!"; binmode $file; print $file ($text); $file->close; $outputed{$opt{revision}} = 1; output_file ($rcs, %opt, revision => $rcs->{delta}->{$opt{revision}}->{next}, previous_text => \$text) if $rcs->{delta}->{$opt{revision}}->{next} and not $outputed{$rcs->{delta}->{$opt{revision}}->{next}}; } sub patch_rcs_diff ($$) { my @src = split /\x0A/, ${+shift}, -1; my @patch = split /\x0A/, ${+shift}, -1; my @result; my $i = 0; while (@patch) { $_ = shift @patch; if (/^a(\d+) (\d+)/) { push @result, @src[$i..$1-1], splice @patch, 0, $2; $i = $1; } elsif (/^d(\d+) (\d+)/) { push @result, @src[$i..$1-2]; $i = $1 - 1 + $2; } else { warn "$0: Invalid diff: ".$_ unless $_ eq ''; } } push @result, @src[$i..$#src]; join "\x0A", @result; } __END__ =head1 NAME splitrcs - Split RCS file =head1 SYNOPSIS splitrcs.pl rcs,v =head1 DESCRIPTION C splits a RCS format version history file into multiple files. Each history entry is saved as a single file, with its filename suffixed by FULL STOP (.) and DIGITs representing last-modified date-time. =head1 BUGS =over 4 =item * This script does not support branches yet. =item * C<--help> should display help message. =back =head1 SEE ALSO rcsfile(5), C, C =head1 LICENSE Copyright 2004 Wakaba . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut # $Date: 2004/01/25 07:55:12 $