1*10355SAli.Bahrami@Sun.COM#!/usr/bin/perl -w 2*10355SAli.Bahrami@Sun.COM# 3*10355SAli.Bahrami@Sun.COM# CDDL HEADER START 4*10355SAli.Bahrami@Sun.COM# 5*10355SAli.Bahrami@Sun.COM# The contents of this file are subject to the terms of the 6*10355SAli.Bahrami@Sun.COM# Common Development and Distribution License (the "License"). 7*10355SAli.Bahrami@Sun.COM# You may not use this file except in compliance with the License. 8*10355SAli.Bahrami@Sun.COM# 9*10355SAli.Bahrami@Sun.COM# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*10355SAli.Bahrami@Sun.COM# or http://www.opensolaris.org/os/licensing. 11*10355SAli.Bahrami@Sun.COM# See the License for the specific language governing permissions 12*10355SAli.Bahrami@Sun.COM# and limitations under the License. 13*10355SAli.Bahrami@Sun.COM# 14*10355SAli.Bahrami@Sun.COM# When distributing Covered Code, include this CDDL HEADER in each 15*10355SAli.Bahrami@Sun.COM# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*10355SAli.Bahrami@Sun.COM# If applicable, add the following below this CDDL HEADER, with the 17*10355SAli.Bahrami@Sun.COM# fields enclosed by brackets "[]" replaced with your own identifying 18*10355SAli.Bahrami@Sun.COM# information: Portions Copyright [yyyy] [name of copyright owner] 19*10355SAli.Bahrami@Sun.COM# 20*10355SAli.Bahrami@Sun.COM# CDDL HEADER END 21*10355SAli.Bahrami@Sun.COM# 22*10355SAli.Bahrami@Sun.COM 23*10355SAli.Bahrami@Sun.COM# 24*10355SAli.Bahrami@Sun.COM# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25*10355SAli.Bahrami@Sun.COM# Use is subject to license terms. 26*10355SAli.Bahrami@Sun.COM# 27*10355SAli.Bahrami@Sun.COM 28*10355SAli.Bahrami@Sun.COM# 29*10355SAli.Bahrami@Sun.COM# interface_cmp audits two interface definition files (as created by 30*10355SAli.Bahrami@Sun.COM# interface_check) against one another, and confirms that: 31*10355SAli.Bahrami@Sun.COM# 32*10355SAli.Bahrami@Sun.COM# o All versioned libraries that were present in the previous interface 33*10355SAli.Bahrami@Sun.COM# are present in the new interface 34*10355SAli.Bahrami@Sun.COM# 35*10355SAli.Bahrami@Sun.COM# o for each non-private interface in a library confirm that no symbols 36*10355SAli.Bahrami@Sun.COM# have been removed and that no symbols have been added to it between 37*10355SAli.Bahrami@Sun.COM# the two revisions 38*10355SAli.Bahrami@Sun.COM# 39*10355SAli.Bahrami@Sun.COM# Return codes: 40*10355SAli.Bahrami@Sun.COM# 41*10355SAli.Bahrami@Sun.COM# 0 All interfaces in the new release are identical in old release. 42*10355SAli.Bahrami@Sun.COM# 1 Something is different refer to the error messages. 43*10355SAli.Bahrami@Sun.COM 44*10355SAli.Bahrami@Sun.COM 45*10355SAli.Bahrami@Sun.COMuse strict; 46*10355SAli.Bahrami@Sun.COM 47*10355SAli.Bahrami@Sun.COMuse POSIX qw(getenv); 48*10355SAli.Bahrami@Sun.COMuse Getopt::Std; 49*10355SAli.Bahrami@Sun.COMuse File::Basename; 50*10355SAli.Bahrami@Sun.COM 51*10355SAli.Bahrami@Sun.COM#### Define all global variables (required for strict) 52*10355SAli.Bahrami@Sun.COMuse vars qw($Prog); 53*10355SAli.Bahrami@Sun.COMuse vars qw(%opt); 54*10355SAli.Bahrami@Sun.COMuse vars qw(%old_hash %old_alias %new_hash %new_alias); 55*10355SAli.Bahrami@Sun.COM 56*10355SAli.Bahrami@Sun.COM# Exception Arrays: 57*10355SAli.Bahrami@Sun.COM# 58*10355SAli.Bahrami@Sun.COM# The ADDSYM and DELSYM exceptions are maintained on the @AddSymList 59*10355SAli.Bahrami@Sun.COM# and @DelSymList arrays, respectively. Each array element is a reference 60*10355SAli.Bahrami@Sun.COM# to a subarray of triples: 61*10355SAli.Bahrami@Sun.COM# (sym_re, ver_re, obj_re) 62*10355SAli.Bahrami@Sun.COM# where each item in the tripple is a regular expression, used to 63*10355SAli.Bahrami@Sun.COM# match a particular symbol/version/object combination. 64*10355SAli.Bahrami@Sun.COM# 65*10355SAli.Bahrami@Sun.COM# The EMPTY_TOPVERSION exceptions are maintained on the @EmptyTopVerList 66*10355SAli.Bahrami@Sun.COM# array. Each array element is a reference to a subarray of pairs: 67*10355SAli.Bahrami@Sun.COM# (ver_re, obj_re) 68*10355SAli.Bahrami@Sun.COM# where each item in the pair is a regular expression, used to 69*10355SAli.Bahrami@Sun.COM# match a particular version/object combination. 70*10355SAli.Bahrami@Sun.COM# 71*10355SAli.Bahrami@Sun.COMuse vars qw(@AddSymList @DelSymList @EmptyTopVerList); 72*10355SAli.Bahrami@Sun.COM 73*10355SAli.Bahrami@Sun.COM 74*10355SAli.Bahrami@Sun.COM## LoadExceptions 75*10355SAli.Bahrami@Sun.COM# 76*10355SAli.Bahrami@Sun.COM# Locate the exceptions file and process its contents. We can't use 77*10355SAli.Bahrami@Sun.COM# onbld_elfmod::LoadExceptionsToEXRE() for this, because our exceptions 78*10355SAli.Bahrami@Sun.COM# need to support more than a single regular expression. 79*10355SAli.Bahrami@Sun.COM# 80*10355SAli.Bahrami@Sun.COM# exit: 81*10355SAli.Bahrami@Sun.COM# @AddSymList, @DelSymList, and @EmptyTopVerList have been updated 82*10355SAli.Bahrami@Sun.COM# 83*10355SAli.Bahrami@Sun.COM# note: 84*10355SAli.Bahrami@Sun.COM# We expand strings of the form MACH(dir) to match the given 85*10355SAli.Bahrami@Sun.COM# directory as well as any 64-bit architecture subdirectory that 86*10355SAli.Bahrami@Sun.COM# might be present (i.e. amd64, sparcv9). 87*10355SAli.Bahrami@Sun.COM# 88*10355SAli.Bahrami@Sun.COMsub LoadExceptions { 89*10355SAli.Bahrami@Sun.COM my $file; 90*10355SAli.Bahrami@Sun.COM my $Line; 91*10355SAli.Bahrami@Sun.COM my $LineNum = 0; 92*10355SAli.Bahrami@Sun.COM my $err = 0; 93*10355SAli.Bahrami@Sun.COM 94*10355SAli.Bahrami@Sun.COM # Locate the exception file 95*10355SAli.Bahrami@Sun.COM FILE: { 96*10355SAli.Bahrami@Sun.COM # If -e is specified, that file must be used 97*10355SAli.Bahrami@Sun.COM if ($opt{e}) { 98*10355SAli.Bahrami@Sun.COM $file = $opt{e}; 99*10355SAli.Bahrami@Sun.COM last FILE; 100*10355SAli.Bahrami@Sun.COM } 101*10355SAli.Bahrami@Sun.COM 102*10355SAli.Bahrami@Sun.COM # If this is an activated workspace, use the exception 103*10355SAli.Bahrami@Sun.COM # file found in the exceptions_list directory. 104*10355SAli.Bahrami@Sun.COM if (defined($ENV{CODEMGR_WS})) { 105*10355SAli.Bahrami@Sun.COM $file = "$ENV{CODEMGR_WS}/exception_lists/interface_cmp"; 106*10355SAli.Bahrami@Sun.COM last FILE if (-f $file); 107*10355SAli.Bahrami@Sun.COM } 108*10355SAli.Bahrami@Sun.COM 109*10355SAli.Bahrami@Sun.COM # As a final backstop, the SUNWonbld package provides a 110*10355SAli.Bahrami@Sun.COM # copy of the exception file. This can be useful if we 111*10355SAli.Bahrami@Sun.COM # are being used with an older workspace. 112*10355SAli.Bahrami@Sun.COM # 113*10355SAli.Bahrami@Sun.COM # This script is installed in the SUNWonbld bin directory, 114*10355SAli.Bahrami@Sun.COM # while the exception file is in etc/exception_lists. Find 115*10355SAli.Bahrami@Sun.COM # it relative to the script location given by $0. 116*10355SAli.Bahrami@Sun.COM $file = dirname($0) . "/../etc/exception_lists/interface_cmp"; 117*10355SAli.Bahrami@Sun.COM last FILE if (-f $file); 118*10355SAli.Bahrami@Sun.COM 119*10355SAli.Bahrami@Sun.COM # No exception file was found. 120*10355SAli.Bahrami@Sun.COM return; 121*10355SAli.Bahrami@Sun.COM } 122*10355SAli.Bahrami@Sun.COM 123*10355SAli.Bahrami@Sun.COM open (EFILE, $file) || 124*10355SAli.Bahrami@Sun.COM die "$Prog: unable to open exceptions file: $file"; 125*10355SAli.Bahrami@Sun.COM while ($Line = onbld_elfmod::GetLine(\*EFILE, \$LineNum)) { 126*10355SAli.Bahrami@Sun.COM 127*10355SAli.Bahrami@Sun.COM # Expand MACH() 128*10355SAli.Bahrami@Sun.COM $Line =~ s/MACH\(([^)]+)\)/$1(\/amd64|\/sparcv9)?/g; 129*10355SAli.Bahrami@Sun.COM 130*10355SAli.Bahrami@Sun.COM if ($Line =~ /^DELSYM\s+/) { 131*10355SAli.Bahrami@Sun.COM my ($item, $sym_re, $ver_re, $obj_re) = 132*10355SAli.Bahrami@Sun.COM split(/\s+/, $Line, 4); 133*10355SAli.Bahrami@Sun.COM push @DelSymList, [ $sym_re, $ver_re, $obj_re ]; 134*10355SAli.Bahrami@Sun.COM next; 135*10355SAli.Bahrami@Sun.COM } 136*10355SAli.Bahrami@Sun.COM 137*10355SAli.Bahrami@Sun.COM if ($Line =~ /^ADDSYM\s+/) { 138*10355SAli.Bahrami@Sun.COM my ($item, $sym_re, $ver_re, $obj_re) = 139*10355SAli.Bahrami@Sun.COM split(/\s+/, $Line, 4); 140*10355SAli.Bahrami@Sun.COM push @AddSymList, [ $sym_re, $ver_re, $obj_re ]; 141*10355SAli.Bahrami@Sun.COM next; 142*10355SAli.Bahrami@Sun.COM } 143*10355SAli.Bahrami@Sun.COM 144*10355SAli.Bahrami@Sun.COM if ($Line =~ /^EMPTY_TOPVERSION\s+/) { 145*10355SAli.Bahrami@Sun.COM my ($item, $ver_re, $obj_re) = split(/\s+/, $Line, 3); 146*10355SAli.Bahrami@Sun.COM push @EmptyTopVerList, [ $ver_re, $obj_re ]; 147*10355SAli.Bahrami@Sun.COM next; 148*10355SAli.Bahrami@Sun.COM } 149*10355SAli.Bahrami@Sun.COM 150*10355SAli.Bahrami@Sun.COM $err++; 151*10355SAli.Bahrami@Sun.COM printf(STDERR "$file: Unrecognized option: ". 152*10355SAli.Bahrami@Sun.COM "line $LineNum: $Line\n"); 153*10355SAli.Bahrami@Sun.COM } 154*10355SAli.Bahrami@Sun.COM close EFILE; 155*10355SAli.Bahrami@Sun.COM 156*10355SAli.Bahrami@Sun.COM exit 1 if ($err != 0); 157*10355SAli.Bahrami@Sun.COM} 158*10355SAli.Bahrami@Sun.COM 159*10355SAli.Bahrami@Sun.COM## ExSym(SymList, sym, ver, obj) 160*10355SAli.Bahrami@Sun.COM# 161*10355SAli.Bahrami@Sun.COM# Compare a given symbol/version/object combination against the 162*10355SAli.Bahrami@Sun.COM# exceptions found in the given list. 163*10355SAli.Bahrami@Sun.COM# 164*10355SAli.Bahrami@Sun.COM# entry: 165*10355SAli.Bahrami@Sun.COM# SymList - Reference to @AddSymList, or @DelSymList. 166*10355SAli.Bahrami@Sun.COM# sym, ver, obj - Combination to be compared against exception list 167*10355SAli.Bahrami@Sun.COM# 168*10355SAli.Bahrami@Sun.COM# exit: 169*10355SAli.Bahrami@Sun.COM# Returns True (1) if there is a match, and False (0) otherwise. 170*10355SAli.Bahrami@Sun.COM# 171*10355SAli.Bahrami@Sun.COMsub ExSym { 172*10355SAli.Bahrami@Sun.COM my ($SymList, $sym, $ver, $obj) = @_; 173*10355SAli.Bahrami@Sun.COM 174*10355SAli.Bahrami@Sun.COM foreach my $ex (@$SymList) { 175*10355SAli.Bahrami@Sun.COM return 1 if ($obj =~ /$$ex[2]/) && ($ver =~ /$$ex[1]/) && 176*10355SAli.Bahrami@Sun.COM ($sym =~ /$$ex[0]/); 177*10355SAli.Bahrami@Sun.COM } 178*10355SAli.Bahrami@Sun.COM 179*10355SAli.Bahrami@Sun.COM return 0; 180*10355SAli.Bahrami@Sun.COM} 181*10355SAli.Bahrami@Sun.COM 182*10355SAli.Bahrami@Sun.COM## ExTopVer(ver, obj) 183*10355SAli.Bahrami@Sun.COM# 184*10355SAli.Bahrami@Sun.COM# Compare a given version/object combination against the pairs found 185*10355SAli.Bahrami@Sun.COM# in @EmptyTopVerList. 186*10355SAli.Bahrami@Sun.COM# 187*10355SAli.Bahrami@Sun.COM# entry: 188*10355SAli.Bahrami@Sun.COM# ver, obj - Combination to be compared against empty top version list 189*10355SAli.Bahrami@Sun.COM# 190*10355SAli.Bahrami@Sun.COM# exit: 191*10355SAli.Bahrami@Sun.COM# Returns True (1) if there is a match, and False (0) otherwise. 192*10355SAli.Bahrami@Sun.COM# 193*10355SAli.Bahrami@Sun.COMsub ExTopVer { 194*10355SAli.Bahrami@Sun.COM my ($ver, $obj) = @_; 195*10355SAli.Bahrami@Sun.COM 196*10355SAli.Bahrami@Sun.COM foreach my $ex (@EmptyTopVerList) { 197*10355SAli.Bahrami@Sun.COM return 1 if ($obj =~ /$$ex[1]/) && ($ver =~ /$$ex[0]/); 198*10355SAli.Bahrami@Sun.COM } 199*10355SAli.Bahrami@Sun.COM 200*10355SAli.Bahrami@Sun.COM return 0; 201*10355SAli.Bahrami@Sun.COM} 202*10355SAli.Bahrami@Sun.COM 203*10355SAli.Bahrami@Sun.COM## ExpandInheritance(objhashref) 204*10355SAli.Bahrami@Sun.COM# 205*10355SAli.Bahrami@Sun.COM# For each version contained in the specified object hash reference, 206*10355SAli.Bahrami@Sun.COM# add the inherited symbols. 207*10355SAli.Bahrami@Sun.COM# 208*10355SAli.Bahrami@Sun.COMsub ExpandInheritance { 209*10355SAli.Bahrami@Sun.COM my $obj = $_[0]; 210*10355SAli.Bahrami@Sun.COM 211*10355SAli.Bahrami@Sun.COM # Versions to process. Typically, inheriting versions come before 212*10355SAli.Bahrami@Sun.COM # the versions they inherit. Processing the list in reverse order 213*10355SAli.Bahrami@Sun.COM # maximizes the odds that a needed sub-version will have already 214*10355SAli.Bahrami@Sun.COM # have been processed. 215*10355SAli.Bahrami@Sun.COM my @vers = reverse(@{$obj->{'VERSION_NAMES'}}); 216*10355SAli.Bahrami@Sun.COM 217*10355SAli.Bahrami@Sun.COM # Versions to process in the next pass 218*10355SAli.Bahrami@Sun.COM my @next_vers = (); 219*10355SAli.Bahrami@Sun.COM 220*10355SAli.Bahrami@Sun.COM # Hash, indexed by version name, that reflects whether the version 221*10355SAli.Bahrami@Sun.COM # has been expanded yet or not. 222*10355SAli.Bahrami@Sun.COM my %done = (); 223*10355SAli.Bahrami@Sun.COM 224*10355SAli.Bahrami@Sun.COM while (scalar(@vers) > 0) { 225*10355SAli.Bahrami@Sun.COM foreach my $name (@vers) { 226*10355SAli.Bahrami@Sun.COM my $i; 227*10355SAli.Bahrami@Sun.COM my $defer = 0; 228*10355SAli.Bahrami@Sun.COM my $cur_version = $obj->{'VERSION_INFO'}{$name}; 229*10355SAli.Bahrami@Sun.COM my ($top, $direct, $total, $symhash, $inheritarr) = 230*10355SAli.Bahrami@Sun.COM @{$cur_version}; 231*10355SAli.Bahrami@Sun.COM 232*10355SAli.Bahrami@Sun.COM # In order to expand this version, all the inherited 233*10355SAli.Bahrami@Sun.COM # versions must already have been done. If not, put 234*10355SAli.Bahrami@Sun.COM # this version on @next_vers for the next pass. 235*10355SAli.Bahrami@Sun.COM my $num = scalar(@$inheritarr); 236*10355SAli.Bahrami@Sun.COM for ($i = 0; $i < $num; $i++) { 237*10355SAli.Bahrami@Sun.COM if (!$done{$inheritarr->[$i]}) { 238*10355SAli.Bahrami@Sun.COM $defer = 1; 239*10355SAli.Bahrami@Sun.COM push @next_vers, $name; 240*10355SAli.Bahrami@Sun.COM last; 241*10355SAli.Bahrami@Sun.COM } 242*10355SAli.Bahrami@Sun.COM } 243*10355SAli.Bahrami@Sun.COM next if ($defer); 244*10355SAli.Bahrami@Sun.COM 245*10355SAli.Bahrami@Sun.COM # Add all the symbols from the inherited versions 246*10355SAli.Bahrami@Sun.COM # to this one. 247*10355SAli.Bahrami@Sun.COM for ($i = 0; $i < $num; $i++) { 248*10355SAli.Bahrami@Sun.COM my $i_version = 249*10355SAli.Bahrami@Sun.COM $obj->{'VERSION_INFO'}{$inheritarr->[$i]}; 250*10355SAli.Bahrami@Sun.COM my $i_symhash = $i_version->[3]; 251*10355SAli.Bahrami@Sun.COM 252*10355SAli.Bahrami@Sun.COM foreach my $sym (keys %$i_symhash) { 253*10355SAli.Bahrami@Sun.COM if (!defined($cur_version->[3]{$sym})) { 254*10355SAli.Bahrami@Sun.COM $cur_version->[2]++; 255*10355SAli.Bahrami@Sun.COM $cur_version->[3]{$sym} = 'INHERIT'; 256*10355SAli.Bahrami@Sun.COM } 257*10355SAli.Bahrami@Sun.COM } 258*10355SAli.Bahrami@Sun.COM } 259*10355SAli.Bahrami@Sun.COM 260*10355SAli.Bahrami@Sun.COM $done{$name} = 1; 261*10355SAli.Bahrami@Sun.COM } 262*10355SAli.Bahrami@Sun.COM 263*10355SAli.Bahrami@Sun.COM @vers = @next_vers; 264*10355SAli.Bahrami@Sun.COM @next_vers = (); 265*10355SAli.Bahrami@Sun.COM } 266*10355SAli.Bahrami@Sun.COM} 267*10355SAli.Bahrami@Sun.COM 268*10355SAli.Bahrami@Sun.COM## ReadInterface(file, alias) 269*10355SAli.Bahrami@Sun.COM# 270*10355SAli.Bahrami@Sun.COM# Read the interface description file, as produced by interface_check, and 271*10355SAli.Bahrami@Sun.COM# return a hash describing it. 272*10355SAli.Bahrami@Sun.COM# 273*10355SAli.Bahrami@Sun.COM# entry: 274*10355SAli.Bahrami@Sun.COM# file - Interface file to read. 275*10355SAli.Bahrami@Sun.COM# alias - Refence to hash to be filled in with any aliases 276*10355SAli.Bahrami@Sun.COM# that are seen in the file. The alias name is the key, 277*10355SAli.Bahrami@Sun.COM# and the object is the value. 278*10355SAli.Bahrami@Sun.COM# 279*10355SAli.Bahrami@Sun.COM# exit: 280*10355SAli.Bahrami@Sun.COM# The hash referenced by alias has been updated. 281*10355SAli.Bahrami@Sun.COM# 282*10355SAli.Bahrami@Sun.COM# The return value is a hash that encapsulates the interface 283*10355SAli.Bahrami@Sun.COM# information. This hash returned uses the object names as the 284*10355SAli.Bahrami@Sun.COM# key. Each key references a sub-hash that contains information 285*10355SAli.Bahrami@Sun.COM# for that object: 286*10355SAli.Bahrami@Sun.COM# 287*10355SAli.Bahrami@Sun.COM# CLASS -> ELFCLASS 288*10355SAli.Bahrami@Sun.COM# TYPE -> ELF type 289*10355SAli.Bahrami@Sun.COM# VERSION_NAMES -> Reference to array [1..n] of version names, in the 290*10355SAli.Bahrami@Sun.COM# order they come from the input file. 291*10355SAli.Bahrami@Sun.COM# VERSION_INFO -> Reference to hash indexed by version name, yielding 292*10355SAli.Bahrami@Sun.COM# a reference to an array containing information about 293*10355SAli.Bahrami@Sun.COM# that version. 294*10355SAli.Bahrami@Sun.COM# 295*10355SAli.Bahrami@Sun.COM# The arrays referenced via VERSION_INFO are of the form: 296*10355SAli.Bahrami@Sun.COM# 297*10355SAli.Bahrami@Sun.COM# (top, new, total, symhashref, inheritarrref) 298*10355SAli.Bahrami@Sun.COM# 299*10355SAli.Bahrami@Sun.COM# where: 300*10355SAli.Bahrami@Sun.COM# top - 1 if version is a TOP_VERSION, 0 for a regular VERSION 301*10355SAli.Bahrami@Sun.COM# new - Number of symbols defined explicitly by version 302*10355SAli.Bahrami@Sun.COM# total - Number of symbols included in version, both new, 303*10355SAli.Bahrami@Sun.COM# and via inheritance. 304*10355SAli.Bahrami@Sun.COM# symhashref - Reference to hash indexed by symbol names, and 305*10355SAli.Bahrami@Sun.COM# yielding true (1). 306*10355SAli.Bahrami@Sun.COM# inheritarrref - Reference to array of names of versions 307*10355SAli.Bahrami@Sun.COM# inherited by this one. 308*10355SAli.Bahrami@Sun.COM# 309*10355SAli.Bahrami@Sun.COMsub ReadInterface { 310*10355SAli.Bahrami@Sun.COM my ($file, $alias) = @_; 311*10355SAli.Bahrami@Sun.COM my %main_hash = (); 312*10355SAli.Bahrami@Sun.COM my $Line; 313*10355SAli.Bahrami@Sun.COM my $LineNum = 0; 314*10355SAli.Bahrami@Sun.COM my $obj_name; 315*10355SAli.Bahrami@Sun.COM my $obj_hash; 316*10355SAli.Bahrami@Sun.COM my $sym_ok = 0; 317*10355SAli.Bahrami@Sun.COM my $cur_version; 318*10355SAli.Bahrami@Sun.COM 319*10355SAli.Bahrami@Sun.COM open(FILE, $file) || die "$Prog: Unable to open: $file"; 320*10355SAli.Bahrami@Sun.COM 321*10355SAli.Bahrami@Sun.COM # Until we see an OBJECT line, nothing else is valid. To 322*10355SAli.Bahrami@Sun.COM # simplify the error handling, use a simple initial loop to 323*10355SAli.Bahrami@Sun.COM # read the file up to that point 324*10355SAli.Bahrami@Sun.COM while ($Line = onbld_elfmod::GetLine(\*FILE, \$LineNum)) { 325*10355SAli.Bahrami@Sun.COM if ($Line =~ s/^OBJECT\s+//i) { 326*10355SAli.Bahrami@Sun.COM $obj_name = $Line; 327*10355SAli.Bahrami@Sun.COM $main_hash{$obj_name} = {}; 328*10355SAli.Bahrami@Sun.COM $obj_hash = $main_hash{$obj_name}; 329*10355SAli.Bahrami@Sun.COM last; 330*10355SAli.Bahrami@Sun.COM } 331*10355SAli.Bahrami@Sun.COM die "$file: OBJECT expected on line $LineNum: $Line\n"; 332*10355SAli.Bahrami@Sun.COM } 333*10355SAli.Bahrami@Sun.COM 334*10355SAli.Bahrami@Sun.COM # Read the remainder of the file 335*10355SAli.Bahrami@Sun.COM while ($Line = onbld_elfmod::GetLine(\*FILE, \$LineNum)) { 336*10355SAli.Bahrami@Sun.COM # Items are parsed in order of decreasing frequency 337*10355SAli.Bahrami@Sun.COM 338*10355SAli.Bahrami@Sun.COM if ($Line =~ 339*10355SAli.Bahrami@Sun.COM /^SYMBOL\s+([^\s]+)$/i) { 340*10355SAli.Bahrami@Sun.COM my $sym = $1; 341*10355SAli.Bahrami@Sun.COM 342*10355SAli.Bahrami@Sun.COM die "$file: SYMBOL not expected on line $LineNum: $Line\n" 343*10355SAli.Bahrami@Sun.COM if !$sym_ok; 344*10355SAli.Bahrami@Sun.COM 345*10355SAli.Bahrami@Sun.COM $cur_version->[1]++; 346*10355SAli.Bahrami@Sun.COM $cur_version->[2]++; 347*10355SAli.Bahrami@Sun.COM $cur_version->[3]{$sym} = 'NEW'; 348*10355SAli.Bahrami@Sun.COM next; 349*10355SAli.Bahrami@Sun.COM } 350*10355SAli.Bahrami@Sun.COM 351*10355SAli.Bahrami@Sun.COM if ($Line =~ /^((TOP_)?VERSION)\s+([^\s]+)(\s+\{(.*)\})?\s*$/i) { 352*10355SAli.Bahrami@Sun.COM my ($top, $name, $inherit) = ($2, $3, $5); 353*10355SAli.Bahrami@Sun.COM 354*10355SAli.Bahrami@Sun.COM $top = defined($top) ? 1 : 0; 355*10355SAli.Bahrami@Sun.COM 356*10355SAli.Bahrami@Sun.COM my @inheritarr = defined($inherit) ? 357*10355SAli.Bahrami@Sun.COM split /[,{\s]+/, $inherit : (); 358*10355SAli.Bahrami@Sun.COM 359*10355SAli.Bahrami@Sun.COM $cur_version = [ $top, 0, 0, {}, \@inheritarr ]; 360*10355SAli.Bahrami@Sun.COM $obj_hash->{'VERSION_INFO'}{$name} = $cur_version; 361*10355SAli.Bahrami@Sun.COM 362*10355SAli.Bahrami@Sun.COM push @{$obj_hash->{'VERSION_NAMES'}}, $name; 363*10355SAli.Bahrami@Sun.COM $sym_ok = 1; 364*10355SAli.Bahrami@Sun.COM next; 365*10355SAli.Bahrami@Sun.COM } 366*10355SAli.Bahrami@Sun.COM 367*10355SAli.Bahrami@Sun.COM if ($Line =~ /^OBJECT\s+([^\s]+)$/i) { 368*10355SAli.Bahrami@Sun.COM my $prev_obj_hash = $obj_hash; 369*10355SAli.Bahrami@Sun.COM $obj_name = $1; 370*10355SAli.Bahrami@Sun.COM $main_hash{$obj_name} = {}; 371*10355SAli.Bahrami@Sun.COM $obj_hash = $main_hash{$obj_name}; 372*10355SAli.Bahrami@Sun.COM 373*10355SAli.Bahrami@Sun.COM # Expand the versions for the object just processed 374*10355SAli.Bahrami@Sun.COM ExpandInheritance($prev_obj_hash); 375*10355SAli.Bahrami@Sun.COM next; 376*10355SAli.Bahrami@Sun.COM } 377*10355SAli.Bahrami@Sun.COM 378*10355SAli.Bahrami@Sun.COM if ($Line =~ /^CLASS\s+([^\s]+)$/i) { 379*10355SAli.Bahrami@Sun.COM $obj_hash->{'CLASS'} = $1; 380*10355SAli.Bahrami@Sun.COM next; 381*10355SAli.Bahrami@Sun.COM } 382*10355SAli.Bahrami@Sun.COM 383*10355SAli.Bahrami@Sun.COM if ($Line =~ /^TYPE\s+([^\s]+)$/i) { 384*10355SAli.Bahrami@Sun.COM $obj_hash->{'TYPE'} = $1; 385*10355SAli.Bahrami@Sun.COM next; 386*10355SAli.Bahrami@Sun.COM } 387*10355SAli.Bahrami@Sun.COM 388*10355SAli.Bahrami@Sun.COM if ($Line =~ /^ALIAS\s+([^\s]+)$/i) { 389*10355SAli.Bahrami@Sun.COM $$alias{$1} = $obj_name; 390*10355SAli.Bahrami@Sun.COM next; 391*10355SAli.Bahrami@Sun.COM } 392*10355SAli.Bahrami@Sun.COM 393*10355SAli.Bahrami@Sun.COM die "$file: unrecognized item on line $LineNum: $Line\n"; 394*10355SAli.Bahrami@Sun.COM } 395*10355SAli.Bahrami@Sun.COM close FILE; 396*10355SAli.Bahrami@Sun.COM 397*10355SAli.Bahrami@Sun.COM # Expand the versions for the final object from the file 398*10355SAli.Bahrami@Sun.COM ExpandInheritance($obj_hash); 399*10355SAli.Bahrami@Sun.COM 400*10355SAli.Bahrami@Sun.COM return %main_hash; 401*10355SAli.Bahrami@Sun.COM} 402*10355SAli.Bahrami@Sun.COM 403*10355SAli.Bahrami@Sun.COM## PrintInterface(main_hash, alias) 404*10355SAli.Bahrami@Sun.COM# 405*10355SAli.Bahrami@Sun.COM# Dump the contents of main_hash and alias to stdout in the same format 406*10355SAli.Bahrami@Sun.COM# used by interface_check to produce the input interface file. This output 407*10355SAli.Bahrami@Sun.COM# should diff cleanly against the original (ignoring the header comments). 408*10355SAli.Bahrami@Sun.COM# 409*10355SAli.Bahrami@Sun.COMsub PrintInterface { 410*10355SAli.Bahrami@Sun.COM my ($main_hash, $alias_hash) = @_; 411*10355SAli.Bahrami@Sun.COM 412*10355SAli.Bahrami@Sun.COM foreach my $obj (sort keys %$main_hash) { 413*10355SAli.Bahrami@Sun.COM print "OBJECT\t$obj\n"; 414*10355SAli.Bahrami@Sun.COM print "CLASS\t$main_hash->{$obj}{'CLASS'}\n"; 415*10355SAli.Bahrami@Sun.COM print "TYPE\t$main_hash->{$obj}{'TYPE'}\n"; 416*10355SAli.Bahrami@Sun.COM 417*10355SAli.Bahrami@Sun.COM # This is inefficient, but good enough for debugging 418*10355SAli.Bahrami@Sun.COM # Look at all the aliases and print those that belong 419*10355SAli.Bahrami@Sun.COM # to this object. 420*10355SAli.Bahrami@Sun.COM foreach my $alias (sort keys %$alias_hash) { 421*10355SAli.Bahrami@Sun.COM print "ALIAS\t$alias\n" 422*10355SAli.Bahrami@Sun.COM if ($obj eq $alias_hash->{$alias}); 423*10355SAli.Bahrami@Sun.COM } 424*10355SAli.Bahrami@Sun.COM 425*10355SAli.Bahrami@Sun.COM next if !defined($main_hash->{$obj}{'VERSION_NAMES'}); 426*10355SAli.Bahrami@Sun.COM 427*10355SAli.Bahrami@Sun.COM my $num = scalar(@{$main_hash->{$obj}{'VERSION_NAMES'}}); 428*10355SAli.Bahrami@Sun.COM my $i; 429*10355SAli.Bahrami@Sun.COM for ($i = 0; $i < $num; $i++) { 430*10355SAli.Bahrami@Sun.COM my $name = $main_hash->{$obj}{'VERSION_NAMES'}[$i]; 431*10355SAli.Bahrami@Sun.COM my ($top, $direct, $total, $symhash, $inheritarr) = 432*10355SAli.Bahrami@Sun.COM @{$main_hash->{$obj}{'VERSION_INFO'}{$name}}; 433*10355SAli.Bahrami@Sun.COM 434*10355SAli.Bahrami@Sun.COM $top = $top ? "TOP_" : ''; 435*10355SAli.Bahrami@Sun.COM 436*10355SAli.Bahrami@Sun.COM my $inherit = (scalar(@$inheritarr) > 0) ? 437*10355SAli.Bahrami@Sun.COM "\t{" . join(', ', @{$inheritarr}) . "}" : ''; 438*10355SAli.Bahrami@Sun.COM 439*10355SAli.Bahrami@Sun.COM print "${top}VERSION\t$name$inherit\n"; 440*10355SAli.Bahrami@Sun.COM 441*10355SAli.Bahrami@Sun.COM foreach my $sym (sort keys %$symhash) { 442*10355SAli.Bahrami@Sun.COM print "\t$symhash->{$sym}\t$sym\n"; 443*10355SAli.Bahrami@Sun.COM } 444*10355SAli.Bahrami@Sun.COM } 445*10355SAli.Bahrami@Sun.COM } 446*10355SAli.Bahrami@Sun.COM} 447*10355SAli.Bahrami@Sun.COM 448*10355SAli.Bahrami@Sun.COM## compare() 449*10355SAli.Bahrami@Sun.COM# 450*10355SAli.Bahrami@Sun.COM# Compare the old interface definition contained in (%old_hash, %old_alias) 451*10355SAli.Bahrami@Sun.COM# with the new interface contained in (%new_hash, %new_alias). 452*10355SAli.Bahrami@Sun.COM# 453*10355SAli.Bahrami@Sun.COMsub compare { 454*10355SAli.Bahrami@Sun.COM foreach my $old_obj (sort keys %old_hash) { 455*10355SAli.Bahrami@Sun.COM my $new_obj = $old_obj; 456*10355SAli.Bahrami@Sun.COM my $Ttl = 0; 457*10355SAli.Bahrami@Sun.COM 458*10355SAli.Bahrami@Sun.COM # If the object does not exist in the new interface, 459*10355SAli.Bahrami@Sun.COM # then see if there's an alias for it. Failing that, 460*10355SAli.Bahrami@Sun.COM # we simply ignore the object. 461*10355SAli.Bahrami@Sun.COM if (!defined($new_hash{$new_obj})) { 462*10355SAli.Bahrami@Sun.COM next if !defined($new_alias{$new_obj}); 463*10355SAli.Bahrami@Sun.COM $new_obj = $new_alias{$new_obj}; 464*10355SAli.Bahrami@Sun.COM } 465*10355SAli.Bahrami@Sun.COM 466*10355SAli.Bahrami@Sun.COM my $old = $old_hash{$old_obj}; 467*10355SAli.Bahrami@Sun.COM my $new = $new_hash{$new_obj}; 468*10355SAli.Bahrami@Sun.COM 469*10355SAli.Bahrami@Sun.COM # Every version in the old object must exist in the new object, 470*10355SAli.Bahrami@Sun.COM # and there must be exactly the same symbols in each. 471*10355SAli.Bahrami@Sun.COM my $num = scalar(@{$old->{'VERSION_NAMES'}}); 472*10355SAli.Bahrami@Sun.COM for (my $i = 0; $i < $num; $i++) { 473*10355SAli.Bahrami@Sun.COM my $name = $old->{'VERSION_NAMES'}[$i]; 474*10355SAli.Bahrami@Sun.COM 475*10355SAli.Bahrami@Sun.COM # New object must have this version 476*10355SAli.Bahrami@Sun.COM if (!defined($new->{'VERSION_INFO'}{$name})) { 477*10355SAli.Bahrami@Sun.COM onbld_elfmod::OutMsg2(\*STDOUT, \$Ttl, $old_obj, 478*10355SAli.Bahrami@Sun.COM $new_obj, "$name: deleted version"); 479*10355SAli.Bahrami@Sun.COM next; 480*10355SAli.Bahrami@Sun.COM } 481*10355SAli.Bahrami@Sun.COM 482*10355SAli.Bahrami@Sun.COM my ($old_top, $old_direct, $old_total, $old_symhash) = 483*10355SAli.Bahrami@Sun.COM @{$old->{'VERSION_INFO'}{$name}}; 484*10355SAli.Bahrami@Sun.COM my ($new_top, $new_direct, $new_total, $new_symhash) = 485*10355SAli.Bahrami@Sun.COM @{$new->{'VERSION_INFO'}{$name}}; 486*10355SAli.Bahrami@Sun.COM 487*10355SAli.Bahrami@Sun.COM # If this is an empty top version, and the old object 488*10355SAli.Bahrami@Sun.COM # has the EMPTY_TOPVERSION exception set, then we 489*10355SAli.Bahrami@Sun.COM # skip it as if it were not present. 490*10355SAli.Bahrami@Sun.COM next if $old_top && ($old_direct == 0) && 491*10355SAli.Bahrami@Sun.COM ExTopVer($name, $old_obj); 492*10355SAli.Bahrami@Sun.COM 493*10355SAli.Bahrami@Sun.COM # We check that every symbol in the old object is 494*10355SAli.Bahrami@Sun.COM # in the new one to detect deleted symbols. We then 495*10355SAli.Bahrami@Sun.COM # check that every symbol in the new object is also 496*10355SAli.Bahrami@Sun.COM # in the old object, to find added symbols. If the 497*10355SAli.Bahrami@Sun.COM # "deleted" check is clean, and the two objects have 498*10355SAli.Bahrami@Sun.COM # the same number of symbols in their versions, then we 499*10355SAli.Bahrami@Sun.COM # can skip the "added" test, because we know that 500*10355SAli.Bahrami@Sun.COM # there is no room for an addition to have happened. 501*10355SAli.Bahrami@Sun.COM # Since most objects satisfy these constraints, we 502*10355SAli.Bahrami@Sun.COM # end up doing roughly half the number of comparisons 503*10355SAli.Bahrami@Sun.COM # that would otherwise be needed. 504*10355SAli.Bahrami@Sun.COM my $check_added_syms = 505*10355SAli.Bahrami@Sun.COM ($old_total == $new_total) ? 0: 1; 506*10355SAli.Bahrami@Sun.COM 507*10355SAli.Bahrami@Sun.COM # Every symbol in the old version must be in the new one 508*10355SAli.Bahrami@Sun.COM foreach my $sym (sort keys %$old_symhash) { 509*10355SAli.Bahrami@Sun.COM if (!defined($new_symhash->{$sym})) { 510*10355SAli.Bahrami@Sun.COM onbld_elfmod::OutMsg2(\*STDOUT, 511*10355SAli.Bahrami@Sun.COM \$Ttl, $old_obj, $new_obj, 512*10355SAli.Bahrami@Sun.COM "$name: deleted interface: $sym") 513*10355SAli.Bahrami@Sun.COM if !ExSym(\@DelSymList, 514*10355SAli.Bahrami@Sun.COM $sym, $name, $new_obj); 515*10355SAli.Bahrami@Sun.COM $check_added_syms = 1; 516*10355SAli.Bahrami@Sun.COM } 517*10355SAli.Bahrami@Sun.COM } 518*10355SAli.Bahrami@Sun.COM 519*10355SAli.Bahrami@Sun.COM # Do the "added" check, unless we can optimize it away. 520*10355SAli.Bahrami@Sun.COM # Every symbol in the new version must be in the old one. 521*10355SAli.Bahrami@Sun.COM if ($check_added_syms) { 522*10355SAli.Bahrami@Sun.COM foreach my $sym (sort keys %$new_symhash) { 523*10355SAli.Bahrami@Sun.COM if (!defined($old_symhash->{$sym})) { 524*10355SAli.Bahrami@Sun.COM next if ExSym(\@AddSymList, 525*10355SAli.Bahrami@Sun.COM $sym, $name, $new_obj); 526*10355SAli.Bahrami@Sun.COM onbld_elfmod::OutMsg2(\*STDOUT, 527*10355SAli.Bahrami@Sun.COM \$Ttl, $old_obj, $new_obj, 528*10355SAli.Bahrami@Sun.COM "$name: added interface: $sym"); 529*10355SAli.Bahrami@Sun.COM } 530*10355SAli.Bahrami@Sun.COM } 531*10355SAli.Bahrami@Sun.COM } 532*10355SAli.Bahrami@Sun.COM 533*10355SAli.Bahrami@Sun.COM # We want to ensure that version numbers in an 534*10355SAli.Bahrami@Sun.COM # inheritance chain don't go up by more than 1 in 535*10355SAli.Bahrami@Sun.COM # any given release. If the version names are in the 536*10355SAli.Bahrami@Sun.COM # standard SUNW_x.y[.z] format, we can compare the 537*10355SAli.Bahrami@Sun.COM # two top versions and see if this has happened. 538*10355SAli.Bahrami@Sun.COM # 539*10355SAli.Bahrami@Sun.COM # For a given SUNW_x.y[.z], valid sucessors would 540*10355SAli.Bahrami@Sun.COM # be SUNW_x.(y+1) or SUNW_x.y.(z+1), where z is 541*10355SAli.Bahrami@Sun.COM # assumed to be 0 if not present. 542*10355SAli.Bahrami@Sun.COM # 543*10355SAli.Bahrami@Sun.COM # This check only makes sense when the new interface 544*10355SAli.Bahrami@Sun.COM # is a direct decendent of the old one, as specified 545*10355SAli.Bahrami@Sun.COM # via the -d option. If the two interfaces are more 546*10355SAli.Bahrami@Sun.COM # than one release apart, we should not do this test. 547*10355SAli.Bahrami@Sun.COM if ($opt{d} && $old_top && !$new_top && 548*10355SAli.Bahrami@Sun.COM ($name =~ /^SUNW_(\d+)\.(\d+)(\.(\d+))?/)) { 549*10355SAli.Bahrami@Sun.COM my $iname1 = "SUNW_$1." . ($2 + 1); 550*10355SAli.Bahrami@Sun.COM my $iname2; 551*10355SAli.Bahrami@Sun.COM if (defined($4)) { 552*10355SAli.Bahrami@Sun.COM $iname2 = "SUNW_$1.$2." . ($4 + 1); 553*10355SAli.Bahrami@Sun.COM } else { 554*10355SAli.Bahrami@Sun.COM $iname2 = "SUNW_$1.$2.1"; 555*10355SAli.Bahrami@Sun.COM } 556*10355SAli.Bahrami@Sun.COM 557*10355SAli.Bahrami@Sun.COM if (defined($new->{'VERSION_INFO'}{$iname1}) || 558*10355SAli.Bahrami@Sun.COM defined($new->{'VERSION_INFO'}{$iname2})) { 559*10355SAli.Bahrami@Sun.COM my $i_top = 560*10355SAli.Bahrami@Sun.COM $new->{'VERSION_INFO'}{$iname1}[0] || 561*10355SAli.Bahrami@Sun.COM $new->{'VERSION_INFO'}{$iname2}[0]; 562*10355SAli.Bahrami@Sun.COM if (!$i_top) { 563*10355SAli.Bahrami@Sun.COM onbld_elfmod::OutMsg2(\*STDOUT, 564*10355SAli.Bahrami@Sun.COM \$Ttl, $old_obj, $new_obj, 565*10355SAli.Bahrami@Sun.COM "$name: inconsistant " . 566*10355SAli.Bahrami@Sun.COM "version increment: " . 567*10355SAli.Bahrami@Sun.COM "expect $iname1 or $iname2 ". 568*10355SAli.Bahrami@Sun.COM "to replace top version"); 569*10355SAli.Bahrami@Sun.COM } 570*10355SAli.Bahrami@Sun.COM } else { 571*10355SAli.Bahrami@Sun.COM onbld_elfmod::OutMsg2(\*STDOUT, 572*10355SAli.Bahrami@Sun.COM \$Ttl, $old_obj, $new_obj, 573*10355SAli.Bahrami@Sun.COM "$name: expected superseding " . 574*10355SAli.Bahrami@Sun.COM "top version to $name not " . 575*10355SAli.Bahrami@Sun.COM "present: $iname1 or $iname2"); 576*10355SAli.Bahrami@Sun.COM } 577*10355SAli.Bahrami@Sun.COM } 578*10355SAli.Bahrami@Sun.COM } 579*10355SAli.Bahrami@Sun.COM 580*10355SAli.Bahrami@Sun.COM 581*10355SAli.Bahrami@Sun.COM # Empty versions in the established interface description 582*10355SAli.Bahrami@Sun.COM # are usually the result of fixing a versioning mistake 583*10355SAli.Bahrami@Sun.COM # at some point in the past. These versions are part of 584*10355SAli.Bahrami@Sun.COM # the public record, and cannot be changed now. However, if 585*10355SAli.Bahrami@Sun.COM # comparing two interface descriptions from the same gate, 586*10355SAli.Bahrami@Sun.COM # flag any empty versions in the new interface description 587*10355SAli.Bahrami@Sun.COM # that are not present in the old one. These have yet to 588*10355SAli.Bahrami@Sun.COM # become part of the official interface, and should be removed 589*10355SAli.Bahrami@Sun.COM # before they do. 590*10355SAli.Bahrami@Sun.COM next if !$opt{d}; 591*10355SAli.Bahrami@Sun.COM 592*10355SAli.Bahrami@Sun.COM $num = scalar(@{$new->{'VERSION_NAMES'}}); 593*10355SAli.Bahrami@Sun.COM for (my $i = 0; $i < $num; $i++) { 594*10355SAli.Bahrami@Sun.COM my $name = $new->{'VERSION_NAMES'}[$i]; 595*10355SAli.Bahrami@Sun.COM 596*10355SAli.Bahrami@Sun.COM # If old object has this version, skip it 597*10355SAli.Bahrami@Sun.COM next if defined($old->{'VERSION_INFO'}{$name}); 598*10355SAli.Bahrami@Sun.COM 599*10355SAli.Bahrami@Sun.COM # If explicitly whitelisted, skip it 600*10355SAli.Bahrami@Sun.COM next if ExTopVer($name, $new_obj); 601*10355SAli.Bahrami@Sun.COM 602*10355SAli.Bahrami@Sun.COM my ($new_top, $new_direct, $new_total, $new_symhash) = 603*10355SAli.Bahrami@Sun.COM @{$new->{'VERSION_INFO'}{$name}}; 604*10355SAli.Bahrami@Sun.COM 605*10355SAli.Bahrami@Sun.COM if ($new_direct == 0) { 606*10355SAli.Bahrami@Sun.COM onbld_elfmod::OutMsg2(\*STDOUT, 607*10355SAli.Bahrami@Sun.COM \$Ttl, $old_obj, $new_obj, 608*10355SAli.Bahrami@Sun.COM "$name: invalid empty new version"); 609*10355SAli.Bahrami@Sun.COM } 610*10355SAli.Bahrami@Sun.COM } 611*10355SAli.Bahrami@Sun.COM } 612*10355SAli.Bahrami@Sun.COM 613*10355SAli.Bahrami@Sun.COM} 614*10355SAli.Bahrami@Sun.COM 615*10355SAli.Bahrami@Sun.COM 616*10355SAli.Bahrami@Sun.COM 617*10355SAli.Bahrami@Sun.COM# ----------------------------------------------------------------------------- 618*10355SAli.Bahrami@Sun.COM 619*10355SAli.Bahrami@Sun.COM# Establish a program name for any error diagnostics. 620*10355SAli.Bahrami@Sun.COMchomp($Prog = `basename $0`); 621*10355SAli.Bahrami@Sun.COM 622*10355SAli.Bahrami@Sun.COM# The onbld_elfmod package is maintained in the same directory as this 623*10355SAli.Bahrami@Sun.COM# script, and is installed in ../lib/perl. Use the local one if present, 624*10355SAli.Bahrami@Sun.COM# and the installed one otherwise. 625*10355SAli.Bahrami@Sun.COMmy $moddir = dirname($0); 626*10355SAli.Bahrami@Sun.COM$moddir = "$moddir/../lib/perl" if ! -f "$moddir/onbld_elfmod.pm"; 627*10355SAli.Bahrami@Sun.COMrequire "$moddir/onbld_elfmod.pm"; 628*10355SAli.Bahrami@Sun.COM 629*10355SAli.Bahrami@Sun.COM# Check that we have arguments. Normally, 2 plain arguments are required, 630*10355SAli.Bahrami@Sun.COM# but if -t is present, only one is allowed. 631*10355SAli.Bahrami@Sun.COMif ((getopts('de:ot', \%opt) == 0) || (scalar(@ARGV) != ($opt{t} ? 1 : 2))) { 632*10355SAli.Bahrami@Sun.COM print "usage: $Prog [-dot] [-e exfile] old new\n"; 633*10355SAli.Bahrami@Sun.COM print "\t[-d]\t\tnew is a direct decendent of old\n"; 634*10355SAli.Bahrami@Sun.COM print "\t[-e exfile]\texceptions file\n"; 635*10355SAli.Bahrami@Sun.COM print "\t[-o]\t\tproduce one-liner output (prefixed with pathname)\n"; 636*10355SAli.Bahrami@Sun.COM print "\t[-t]\tParse old, and recreate to stdout\n"; 637*10355SAli.Bahrami@Sun.COM exit 1; 638*10355SAli.Bahrami@Sun.COM} 639*10355SAli.Bahrami@Sun.COM 640*10355SAli.Bahrami@Sun.COM# Locate and process the exceptions file 641*10355SAli.Bahrami@Sun.COMLoadExceptions(); 642*10355SAli.Bahrami@Sun.COM 643*10355SAli.Bahrami@Sun.COM%old_alias = (); 644*10355SAli.Bahrami@Sun.COM%old_hash = ReadInterface($ARGV[0], \%old_alias); 645*10355SAli.Bahrami@Sun.COM 646*10355SAli.Bahrami@Sun.COM# If -t is present, only one argument is allowed --- we parse it, and then 647*10355SAli.Bahrami@Sun.COM# print the same information back to stderr in the same format as the original. 648*10355SAli.Bahrami@Sun.COM# This is useful for debugging, to verify that the parsing is correct. 649*10355SAli.Bahrami@Sun.COMif ($opt{t}) { 650*10355SAli.Bahrami@Sun.COM PrintInterface(\%old_hash, \%old_alias); 651*10355SAli.Bahrami@Sun.COM exit 0; 652*10355SAli.Bahrami@Sun.COM} 653*10355SAli.Bahrami@Sun.COM 654*10355SAli.Bahrami@Sun.COM%new_alias = (); 655*10355SAli.Bahrami@Sun.COM%new_hash = ReadInterface($ARGV[1], \%new_alias); 656*10355SAli.Bahrami@Sun.COM 657*10355SAli.Bahrami@Sun.COMcompare(); 658*10355SAli.Bahrami@Sun.COM 659*10355SAli.Bahrami@Sun.COMexit 0; 660