#! /usr/local/apps/perl/current/bin/perl ######################################################################################### # Program to read in two files (e.g. name.def, paramId.def, shortName.def or units.def) # and check # 1. They have the same number of parameters # 2. They occur in the same order # 3. And each param is defined in exactly the same way # For each parameter we store its keys in the order encountered # in the files and compare. # # Usage: # $0 file1 file2 # # URLs: # http://perldoc.perl.org/perldsc.html#MORE-ELABORATE-RECORDS ######################################################################################### $|=1; #use strict; use Test::More; use Data::Dumper; #use Algorithm::Diff qw[ diff ]; use Algorithm::Diff::Callback 'diff_hashes'; $extra_info= 0; # Do we print more info? $debug = 0; my $key; my @values; die "Bad args. Expected two files" if (scalar @ARGV < 2); $file1 = $ARGV[0]; $file2 = $ARGV[1]; print "Comparing $file1 and $file2\n"; #die "File extension should be '.def'" if $file1 !~ /\.def$/; #die "File extension should be '.def'" if $file2 !~ /\.def$/; while (my $arg = shift @ARGV){ if ($arg =~ /-D(\w+)=(\w+)/) { $var_name = $1; $value = $2; $$var_name = $value; } } my %map1 = process("$file1"); my %map2 = process("$file2"); my $count1 = scalar(keys %map1); my $count2 = scalar(keys %map2); # Compare hashes if ($compare) { print "Compare hashes...\n"; diff_hashes( \%map1, \%map2, sub { print "\nLost ", shift }, sub { print "\nGained ", shift }, undef, ); } #diff_hashes( # \%map1, # \%map2, # sub { print 'Lost ', shift }, # sub { print 'Gained ', shift }, # sub { # my ( $key, $before, $after ) = @_; # print "$key changed from $before to $after\n"; # }, # ); #@diffs = diff( \%map1, \%map2 ); #exit 0; #print @$_ for map{ # @$_ #} diff( # [ split "\n", Dumper( \%map1 ) ], # [ split "\n", Dumper( \%map2 ) ] #); print "\nTesting now...\n"; ok($count1==$count2, "Same number of elements"); ok($count1 > 0 && $count2 > 0, "Check some params found"); #print "count1=$count1, count2=$count2\n"; # Check name maps are the same is_deeply(\%map1, \%map2, 'Check hashes are the same'); print Data::Dumper->Dump([\%map1], ["Name Map1"]), $/ if ($debug); done_testing(); # ------------------------------------------------------------------------- # Function to return a hash: # key = parameter long name # value = an array holding 1 or more hashes # We use a trick to store the main title e.g. units, paramId in they key "
" # E.g. # hash = { # 'Reactive tracer 10 mass mixing ratio' => [ # { # 'parameterCategory' => '210', # 'parameterNumber' => '149', # 'discipline' => '192' # }, # { # 'parameterCategory' => '211', # 'parameterNumber' => '149', # 'discipline' => '192' # } # ], # 'downward shortwave radiant flux density' => [ # { # 'parameterCategory' => '201', # 'parameterNumber' => '1', # 'discipline' => '192' # } # ], # .... etc # # ------------------------------------------------------------------------- sub process { my ($filename) = @_; open FILE, $filename or die "Tried to open $filename\n$!"; my @lines = ; close(FILE); my %map1 = (); my %map2 = (); # inner map my $lineNum = 0; my $desc = ""; my $this; # a line in file foreach $this (@lines) { $lineNum++; chomp $this; #if ($lineNum == 1 && $this !~ /Automatically generated by/ ) { # die "File: $filename, Line 1: Should say 'Automatically generated'"; #} #next if ($lineNum == 1); # always skip first line # Description line if ($this =~ /^\s*#\s*(.*)\s*/) { $desc = $1; die "File: $filename, Empty description" if ($desc eq ""); } # 'something' = { elsif ($this =~ /^'(.*)'\s*=\s*{\s*$/ && $desc) { $map2{"
"} = $1; } # key = value elsif ($this =~ /(\w+)\s*=\s*([^ ]+)\s*;/ && $desc) { $key = $1; $val = $2; $map2{$key} = $val; } # Hit the end brace elsif ($this =~ /^\s*}\s*$/) { my %map2_copy = %map2; # copy inner hash # Store this inner hash in our array push @{ $map1{$desc} }, \%map2_copy; %map2 = (); # Empty inner map for next param } } return (%map1); }