diff_transcript.pl
By: James Reynolds - Revised: 2006-07-11 devin
Introduction
This is a perl script that will print out differences it finds in two transcripts.
/usr/local/bin/diff_transcript.pl
Usage: diff_transcript.pl
[-togmpdsc] trascript1 trascript2
example: diff_transcript.pl app_version1.T app_version2.T
-t Ignore type
-o Ignore owner
-g Ignore group
-m Ignore mode (permissions)
-p Ignore mode (permissions)
-d Ignore date
-s Ignore size
-c Ignore checksum
Script
diff_transcript.pl#!/usr/bin/perl
################################################################################
# Copyright (c) 2005 University of Utah Student Computing Labs.
# All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appears in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation, and that the name of The University
# of Utah not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission. This software is supplied as is without expressed or
# implied warranties of any kind.
################################################################################
################################################################################
# diff_transcript.pl
# Version 1.0 (2006.07.05)
# Compares 2 Radmind transcripts.
#
################################################################################
################################################################################
sub usage {
my $myname = `basename $0`;
print STDERR << "EOF";
Usage: $myname [-togmpdsc] trascript1 trascript2
example: $myname app_version1.T app_version2.T
-t Ignore type
-o Ignore owner
-g Ignore group
-m Ignore mode (permissions)
-p Ignore mode (permissions)
-d Ignore date
-s Ignore size
-c Ignore checksum
-i Print lines that are identical
EOF
exit 1;
}
####################################
# Get ARGs
#
use Getopt::Std;
getopts("togmpdsci",\%options);
$ignore_type = 1 if defined $options{t};
$ignore_owner = 1 if defined $options{o};
$ignore_group = 1 if defined $options{g};
$ignore_perms = 1 if defined $options{'m'};
$ignore_perms = 1 if defined $options{p};
$ignore_date = 1 if defined $options{d};
$ignore_size = 1 if defined $options{'s'};
$ignore_cksum = 1 if defined $options{c};
$print_same_lines = 1 if defined $options{i};
$t1 = $ARGV[0];
$t2 = $ARGV[1];
if ( ! -e $t1 or ! -e $t2 ) {
usage();
}
if ( open T1, "< $t1" ) {
if ( open T2, "< $t2" ) {
my $t1_advance = 1;
my $t2_advance = 1;
my $t1_eof = 0;
my $t2_eof = 0;
my %t1_item;
my %t2_item;
my $line1;
my $line2;
my $lastdiff;
my $currentdiff;
my $scan = 1;
while ( $scan ) {
# scan each line
if ( $t1_advance ) {
my $keepscanning = 1;
while ($keepscanning) {
if ( $line1 = <T1> ) {
%t1_item = parse_radmind_line($line1);
if ( $t1_item{path} ne "" ) { $keepscanning = 0; }
} else {
$t1_eof = 1;
$keepscanning = 0;
}
}
}
if ( $t2_advance ) {
my $keepscanning = 1;
while ($keepscanning) {
if ( $line2 = <T2> ) {
%t2_item = parse_radmind_line($line2);
if ( $t2_item{path} ne "" ) { $keepscanning = 0; }
} else {
$t2_eof = 1;
$keepscanning = 0;
}
}
}
if ( $t1_eof and $t2_eof ) {
$scan = 0;
} elsif ( $t1_eof ) {
$currentdiff = 1;
if ( $currentdiff != $lastdiff ) { print "--\n"; }
print "> $t2_item{path}\n";
$t1_advance = 0;
$t2_advance = 1;
} elsif ( $t2_eof ) {
$currentdiff = 2;
if ( $currentdiff != $lastdiff ) { print "--\n"; }
print "< $t1_item{path}\n";
$t1_advance = 1;
$t2_advance = 0;
} elsif ( $t1_item{path} gt $t2_item{path} ) {
$currentdiff = 1;
if ( $currentdiff != $lastdiff ) { print "--\n"; }
print "> $t2_item{path}\n";
$t1_advance = 0;
$t2_advance = 1;
} elsif ( $t1_item{path} lt $t2_item{path} ) {
$currentdiff = 2;
if ( $currentdiff != $lastdiff ) { print "--\n"; }
print "< $t1_item{path}\n";
$t1_advance = 1;
$t2_advance = 0;
} elsif ( $t1_item{path} eq $t2_item{path} ) {
my $diff_found = 0;
while (($a,$b) = each %t1_item ) {
if ($ignore_type and $a eq "type" or
$ignore_owner and $a eq "owner" or
$ignore_group and $a eq "group" or
$ignore_perms and $a eq "perms" or
$ignore_date and $a eq "modtime" or
$ignore_size and $a eq "size" or
$ignore_cksum and $a eq "checksum") {
next;
}
if ( $t1_item{$a} ne $t2_item{$a} ) {
if ( ! $diff_found ) {
$currentdiff = 3;
if ( $currentdiff != $lastdiff ) { print "--\n"; }
print "! $t1_item{path} -";
$diff_found = 1;
}
print " $a: $t1_item{$a} != $t2_item{$a};";
}
}
if ( $diff_found ) {
print "\n";
} elsif ( $print_same_lines ) {
$currentdiff = 4;
if ( $currentdiff != $lastdiff ) { print "--\n"; }
print "= $t1_item{path}\n";
}
$t1_advance = 1;
$t2_advance = 1;
} else {
die "$t1_item{path} ?? $t2_item{path}\n";
}
$lastdiff = $currentdiff;
}
close T2;
} else {
entman_logger ( "Could not open $t2: $!" );
}
close T1;
} else {
entman_logger ( "Could not open $t1: $!" );
}
################################################################################
sub parse_radmind_line {
my ( $line ) = @_;
my %radmind_line = ();
# check for comment
if ( ( substr $line, 0, 1 ) eq "#" ) {
$radmind_line{'comment'} = substr $line, 1, length ($line)-1;
return %radmind_line;
}
my @theLine = split (' ', $line);
# check for minus
if ( $theLine[0] eq "-" ) {
shift @theLine;
$radmind_line{'minus'} = 1;
}
# check for plus (even needed?
if ( $theLine[0] eq "+" ) {
shift @theLine;
$radmind_line{'plus'} = 1;
}
$radmind_line{'filetype'} = shift @theLine;
$radmind_line{'path'} = shift @theLine;
$radmind_line{'realpath'} = unescape_radmind_path ( $radmind_line{'path'} );
if ( ( substr $radmind_line{'path'}, 0, 1 ) eq "." ) {
$radmind_line{'relativepath'} = 1;
} elsif ( ( substr $radmind_line{'path'}, 0, 1 ) eq "/" ) {
$radmind_line{'absolutepath'} = 1;
}
if ($radmind_line{'filetype'} ne "l" ) {
$radmind_line{'perms'} = shift @theLine;
$radmind_line{'owner'} = shift @theLine;
$radmind_line{'group'} = shift @theLine;
if ($radmind_line{'filetype'} ne "d" ) {
$radmind_line{'modtime'} = shift @theLine;
$radmind_line{'size'} = shift @theLine;
$radmind_line{'checksum'} = shift @theLine;
} elsif ( $#theLine > 0 ) {
$radmind_line{'appleinfo'} = shift @theLine;
}
} else {
$radmind_line{'linkpath'} = shift @theLine;
}
return %radmind_line;
}
sub unescape_radmind_path {
my ( $path ) = @_;
$path =~ s/\\b/ /g;
# my $path =~ s/\\t/\t/g;; # convert tabs
# my $path =~ s/\\n/\n/g;; # convert newline
# my $path =~ s/\\r/\r/g;; # convert return
# my $path =~ s/\\/\/g;; # convert backslashes
return $path;
}