eccodes/definitions/compare_concepts.pl

165 lines
4.6 KiB
Perl
Executable File

#! /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 "<MAIN>"
# 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 = <FILE>;
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{"<MAIN>"} = $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);
}