diff_transcript.pl

By: James Reynolds - Revised: 2006-07-11 devin

Download Script – ZIP-File, 2.3 KB

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;
}