mkdef.pl revision 72613
1261991Sdim#!/usr/local/bin/perl -w 2218885Sdim# 3218885Sdim# generate a .def file 4218885Sdim# 5218885Sdim# It does this by parsing the header files and looking for the 6218885Sdim# prototyped functions: it then prunes the output. 7218885Sdim# 8218885Sdim# Intermediary files are created, call libeay.num and ssleay.num,... 9218885Sdim# Previously, they had the following format: 10261991Sdim# 11218885Sdim# routine-name nnnn 12218885Sdim# 13218885Sdim# But that isn't enough for a number of reasons, the first on being that 14218885Sdim# this format is (needlessly) very Win32-centric, and even then... 15261991Sdim# One of the biggest problems is that there's no information about what 16261991Sdim# routines should actually be used, which varies with what crypto algorithms 17218885Sdim# are disabled. Also, some operating systems (for example VMS with VAX C) 18218885Sdim# need to keep track of the global variables as well as the functions. 19261991Sdim# 20276479Sdim# So, a remake of this script is done so as to include information on the 21261991Sdim# kind of symbol it is (function or variable) and what algorithms they're 22261991Sdim# part of. This will allow easy translating to .def files or the corresponding 23261991Sdim# file in other operating systems (a .opt file for VMS, possibly with a .mar 24261991Sdim# file). 25218885Sdim# 26276479Sdim# The format now becomes: 27276479Sdim# 28276479Sdim# routine-name nnnn info 29276479Sdim# 30276479Sdim# and the "info" part is actually a colon-separated string of fields with 31261991Sdim# the following meaning: 32218885Sdim# 33261991Sdim# existence:platform:kind:algorithms 34261991Sdim# 35261991Sdim# - "existence" can be "EXIST" or "NOEXIST" depending on if the symbol is 36261991Sdim# found somewhere in the source, 37261991Sdim# - "platforms" is empty if it exists on all platforms, otherwise it contains 38218885Sdim# comma-separated list of the platform, just as they are if the symbol exists 39261991Sdim# for those platforms, or prepended with a "!" if not. This helps resolve 40261991Sdim# symbol name replacements for platforms where the names are too long for the 41296417Sdim# compiler or linker, or if the systems is case insensitive and there is a 42261991Sdim# clash. This script assumes those redefinitions are place in the file 43218885Sdim# crypto/symhacks.h. 44261991Sdim# The semantics for the platforms list is a bit complicated. The rule of 45218885Sdim# thumb is that the list is exclusive, but it seems to mean different things. 46261991Sdim# So, if the list is all negatives (like "!VMS,!WIN16"), the symbol exists 47261991Sdim# on all platforms except those listed. If the list is all positives (like 48280031Sdim# "VMS,WIN16"), the symbol exists only on those platforms and nowhere else. 49218885Sdim# The combination of positives and negatives will act as if the positives 50276479Sdim# weren't there. 51276479Sdim# - "kind" is "FUNCTION" or "VARIABLE". The meaning of that is obvious. 52276479Sdim# - "algorithms" is a comma-separated list of algorithm names. This helps 53276479Sdim# exclude symbols that are part of an algorithm that some user wants to 54276479Sdim# exclude. 55276479Sdim# 56276479Sdim 57218885Sdimmy $crypto_num= "util/libeay.num"; 58218885Sdimmy $ssl_num= "util/ssleay.num"; 59218885Sdim 60261991Sdimmy $do_update = 0; 61261991Sdimmy $do_rewrite = 0; 62280031Sdimmy $do_crypto = 0; 63280031Sdimmy $do_ssl = 0; 64280031Sdimmy $do_ctest = 0; 65280031Sdimmy $do_ctestall = 0; 66280031Sdimmy $rsaref = 0; 67280031Sdim 68280031Sdimmy $VMS=0; 69280031Sdimmy $W32=0; 70280031Sdimmy $W16=0; 71280031Sdimmy $NT=0; 72280031Sdim# Set this to make typesafe STACK definitions appear in DEF 73280031Sdimmy $safe_stack_def = 0; 74280031Sdim 75280031Sdimmy @known_platforms = ( "__FreeBSD__", "VMS", "WIN16", "WIN32", 76280031Sdim "WINNT", "PERL5", "NeXT" ); 77280031Sdimmy @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", 78280031Sdim "CAST", "MD2", "MD4", "MD5", "SHA", "RIPEMD", 79280031Sdim "MDC2", "RSA", "DSA", "DH", "HMAC", "FP_API" ); 80280031Sdim 81280031Sdimmy $options=""; 82280031Sdimopen(IN,"<Makefile.ssl") || die "unable to open Makefile.ssl!\n"; 83288943Sdimwhile(<IN>) { 84280031Sdim $options=$1 if (/^OPTIONS=(.*)$/); 85280031Sdim} 86280031Sdimclose(IN); 87280031Sdim 88280031Sdim# The following ciphers may be excluded (by Configure). This means functions 89280031Sdim# defined with ifndef(NO_XXX) are not included in the .def file, and everything 90280031Sdim# in directory xxx is ignored. 91280031Sdimmy $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf; 92280031Sdimmy $no_cast; 93280031Sdimmy $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2; 94280031Sdimmy $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; 95280031Sdimmy $no_fp_api; 96280031Sdim 97280031Sdimforeach (@ARGV, split(/ /, $options)) 98280031Sdim { 99280031Sdim $W32=1 if $_ eq "32"; 100280031Sdim $W16=1 if $_ eq "16"; 101280031Sdim if($_ eq "NT") { 102280031Sdim $W32 = 1; 103280031Sdim $NT = 1; 104280031Sdim } 105280031Sdim $VMS=1 if $_ eq "VMS"; 106280031Sdim $rsaref=1 if $_ eq "rsaref"; 107280031Sdim 108280031Sdim $do_ssl=1 if $_ eq "ssleay"; 109280031Sdim $do_ssl=1 if $_ eq "ssl"; 110280031Sdim $do_crypto=1 if $_ eq "libeay"; 111280031Sdim $do_crypto=1 if $_ eq "crypto"; 112280031Sdim $do_update=1 if $_ eq "update"; 113280031Sdim $do_rewrite=1 if $_ eq "rewrite"; 114280031Sdim $do_ctest=1 if $_ eq "ctest"; 115280031Sdim $do_ctestall=1 if $_ eq "ctestall"; 116280031Sdim #$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK"; 117280031Sdim 118261991Sdim if (/^no-rc2$/) { $no_rc2=1; } 119218885Sdim elsif (/^no-rc4$/) { $no_rc4=1; } 120261991Sdim elsif (/^no-rc5$/) { $no_rc5=1; } 121261991Sdim elsif (/^no-idea$/) { $no_idea=1; } 122261991Sdim elsif (/^no-des$/) { $no_des=1; $no_mdc2=1; } 123218885Sdim elsif (/^no-bf$/) { $no_bf=1; } 124261991Sdim elsif (/^no-cast$/) { $no_cast=1; } 125261991Sdim elsif (/^no-md2$/) { $no_md2=1; } 126261991Sdim elsif (/^no-md4$/) { $no_md4=1; } 127218885Sdim elsif (/^no-md5$/) { $no_md5=1; } 128261991Sdim elsif (/^no-sha$/) { $no_sha=1; } 129261991Sdim elsif (/^no-ripemd$/) { $no_ripemd=1; } 130261991Sdim elsif (/^no-mdc2$/) { $no_mdc2=1; } 131261991Sdim elsif (/^no-rsa$/) { $no_rsa=1; } 132218885Sdim elsif (/^no-dsa$/) { $no_dsa=1; } 133261991Sdim elsif (/^no-dh$/) { $no_dh=1; } 134261991Sdim elsif (/^no-hmac$/) { $no_hmac=1; } 135261991Sdim } 136218885Sdim 137261991Sdim 138261991Sdim# If no platform is given, assume WIN32 139261991Sdimif ($W32 + $W16 + $VMS == 0) { 140261991Sdim $W32 = 1; 141218885Sdim} 142261991Sdim 143218885Sdim# Add extra knowledge 144218885Sdimif ($W16) { 145261991Sdim $no_fp_api=1; 146261991Sdim} 147261991Sdim 148261991Sdimif (!$do_ssl && !$do_crypto) 149261991Sdim { 150261991Sdim print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT ] [rsaref]\n"; 151261991Sdim exit(1); 152218885Sdim } 153218885Sdim 154309124Sdim%ssl_list=&load_numbers($ssl_num); 155309124Sdim$max_ssl = $max_num; 156309124Sdim%crypto_list=&load_numbers($crypto_num); 157309124Sdim$max_crypto = $max_num; 158309124Sdim 159309124Sdimmy $ssl="ssl/ssl.h"; 160309124Sdim 161309124Sdimmy $crypto ="crypto/crypto.h"; 162309124Sdim$crypto.=" crypto/des/des.h" unless $no_des; 163309124Sdim$crypto.=" crypto/idea/idea.h" unless $no_idea; 164309124Sdim$crypto.=" crypto/rc4/rc4.h" unless $no_rc4; 165309124Sdim$crypto.=" crypto/rc5/rc5.h" unless $no_rc5; 166309124Sdim$crypto.=" crypto/rc2/rc2.h" unless $no_rc2; 167314564Sdim$crypto.=" crypto/bf/blowfish.h" unless $no_bf; 168314564Sdim$crypto.=" crypto/cast/cast.h" unless $no_cast; 169314564Sdim$crypto.=" crypto/md2/md2.h" unless $no_md2; 170314564Sdim$crypto.=" crypto/md4/md4.h" unless $no_md4; 171314564Sdim$crypto.=" crypto/md5/md5.h" unless $no_md5; 172309124Sdim$crypto.=" crypto/mdc2/mdc2.h" unless $no_mdc2; 173309124Sdim$crypto.=" crypto/sha/sha.h" unless $no_sha; 174314564Sdim$crypto.=" crypto/ripemd/ripemd.h" unless $no_ripemd; 175314564Sdim 176314564Sdim$crypto.=" crypto/bn/bn.h"; 177314564Sdim$crypto.=" crypto/rsa/rsa.h" unless $no_rsa; 178314564Sdim$crypto.=" crypto/dsa/dsa.h" unless $no_dsa; 179218885Sdim$crypto.=" crypto/dh/dh.h" unless $no_dh; 180218885Sdim$crypto.=" crypto/hmac/hmac.h" unless $no_hmac; 181276479Sdim 182261991Sdim$crypto.=" crypto/stack/stack.h"; 183261991Sdim$crypto.=" crypto/buffer/buffer.h"; 184218885Sdim$crypto.=" crypto/bio/bio.h"; 185261991Sdim$crypto.=" crypto/dso/dso.h"; 186261991Sdim$crypto.=" crypto/lhash/lhash.h"; 187261991Sdim$crypto.=" crypto/conf/conf.h"; 188218885Sdim$crypto.=" crypto/txt_db/txt_db.h"; 189261991Sdim 190261991Sdim$crypto.=" crypto/evp/evp.h"; 191288943Sdim$crypto.=" crypto/objects/objects.h"; 192218885Sdim$crypto.=" crypto/pem/pem.h"; 193261991Sdim#$crypto.=" crypto/meth/meth.h"; 194261991Sdim$crypto.=" crypto/asn1/asn1.h"; 195261991Sdim$crypto.=" crypto/asn1/asn1_mac.h"; 196261991Sdim$crypto.=" crypto/err/err.h"; 197261991Sdim$crypto.=" crypto/pkcs7/pkcs7.h"; 198261991Sdim$crypto.=" crypto/pkcs12/pkcs12.h"; 199261991Sdim$crypto.=" crypto/x509/x509.h"; 200261991Sdim$crypto.=" crypto/x509/x509_vfy.h"; 201218885Sdim$crypto.=" crypto/x509v3/x509v3.h"; 202218885Sdim$crypto.=" crypto/rand/rand.h"; 203296417Sdim$crypto.=" crypto/comp/comp.h"; 204296417Sdim$crypto.=" crypto/tmdiff.h"; 205261991Sdim 206218885Sdimmy $symhacks="crypto/symhacks.h"; 207280031Sdim 208261991Sdimmy @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks); 209218885Sdimmy @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks); 210261991Sdim 211276479Sdimif ($do_update) { 212276479Sdim 213288943Sdimif ($do_ssl == 1) { 214276479Sdim 215218885Sdim &maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols); 216276479Sdim if ($do_rewrite == 1) { 217218885Sdim open(OUT, ">$ssl_num"); 218218885Sdim &rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols); 219276479Sdim close OUT; 220276479Sdim } else { 221261991Sdim open(OUT, ">>$ssl_num"); 222261991Sdim } 223261991Sdim &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols); 224280031Sdim close OUT; 225276479Sdim} 226280031Sdim 227276479Sdimif($do_crypto == 1) { 228218885Sdim 229276479Sdim &maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols); 230288943Sdim if ($do_rewrite == 1) { 231218885Sdim open(OUT, ">$crypto_num"); 232276479Sdim &rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols); 233218885Sdim } else { 234218885Sdim open(OUT, ">>$crypto_num"); 235314564Sdim } 236314564Sdim &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols); 237314564Sdim close OUT; 238314564Sdim} 239276479Sdim 240261991Sdim} elsif ($do_ctest || $do_ctestall) { 241218885Sdim 242276479Sdim print <<"EOF"; 243276479Sdim 244276479Sdim/* Test file to check all DEF file symbols are present by trying 245276479Sdim * to link to all of them. This is *not* intended to be run! 246276479Sdim */ 247261991Sdim 248261991Sdimint main() 249280031Sdim{ 250261991SdimEOF 251261991Sdim &print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols) 252276479Sdim if $do_ssl == 1; 253261991Sdim 254288943Sdim &print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols) 255276479Sdim if $do_crypto == 1; 256276479Sdim 257276479Sdim print "}\n"; 258276479Sdim 259261991Sdim} else { 260276479Sdim 261288943Sdim &print_def_file(*STDOUT,"SSLEAY",*ssl_list,@ssl_symbols) 262276479Sdim if $do_ssl == 1; 263276479Sdim 264276479Sdim &print_def_file(*STDOUT,"LIBEAY",*crypto_list,@crypto_symbols) 265276479Sdim if $do_crypto == 1; 266218885Sdim 267218885Sdim} 268276479Sdim 269261991Sdim 270261991Sdimsub do_defs 271261991Sdim{ 272280031Sdim my($name,$files,$symhacksfile)=@_; 273276479Sdim my $file; 274280031Sdim my @ret; 275276479Sdim my %syms; 276261991Sdim my %platform; # For anything undefined, we assume "" 277276479Sdim my %kind; # For anything undefined, we assume "FUNCTION" 278296417Sdim my %algorithm; # For anything undefined, we assume "" 279309124Sdim my %rename; 280296417Sdim my $cpp; 281296417Sdim 282296417Sdim foreach $file (split(/\s+/,$symhacksfile." ".$files)) 283309124Sdim { 284309124Sdim open(IN,"<$file") || die "unable to open $file:$!\n"; 285261991Sdim my $line = "", my $def= ""; 286309124Sdim my %tag = ( 287309124Sdim (map { $_ => 0 } @known_platforms), 288296417Sdim (map { "NO_".$_ => 0 } @known_algorithms), 289309124Sdim NOPROTO => 0, 290309124Sdim PERL5 => 0, 291309124Sdim _WINDLL => 0, 292309124Sdim CONST_STRICT => 0, 293309124Sdim TRUE => 1, 294296417Sdim ); 295309124Sdim my $symhacking = $file eq $symhacksfile; 296309124Sdim while(<IN>) { 297309124Sdim last if (/BEGIN ERROR CODES/); 298309124Sdim if ($line ne '') { 299309124Sdim $_ = $line . $_; 300309124Sdim $line = ''; 301309124Sdim } 302309124Sdim 303309124Sdim if (/\\$/) { 304309124Sdim $line = $_; 305309124Sdim next; 306309124Sdim } 307309124Sdim 308309124Sdim $cpp = 1 if /^\#.*ifdef.*cplusplus/; 309309124Sdim if ($cpp) { 310309124Sdim $cpp = 0 if /^\#.*endif/; 311309124Sdim next; 312309124Sdim } 313309124Sdim 314309124Sdim s/\/\*.*?\*\///gs; # ignore comments 315309124Sdim s/{[^{}]*}//gs; # ignore {} blocks 316309124Sdim if (/^\#\s*ifndef (.*)/) { 317261991Sdim push(@tag,$1); 318261991Sdim $tag{$1}=-1; 319276479Sdim } elsif (/^\#\s*if !defined\(([^\)]+)\)/) { 320296417Sdim push(@tag,$1); 321296417Sdim $tag{$1}=-1; 322296417Sdim } elsif (/^\#\s*ifdef (.*)/) { 323296417Sdim push(@tag,$1); 324261991Sdim $tag{$1}=1; 325261991Sdim } elsif (/^\#\s*if defined\(([^\)]+)\)/) { 326261991Sdim push(@tag,$1); 327218885Sdim $tag{$1}=1; 328218885Sdim } elsif (/^\#\s*error\s+(\w+) is disabled\./) { 329280031Sdim if ($tag[$#tag] eq "NO_".$1) { 330261991Sdim $tag{$tag[$#tag]}=2; 331280031Sdim } 332261991Sdim } elsif (/^\#\s*endif/) { 333280031Sdim if ($tag{$tag[$#tag]}==2) { 334261991Sdim $tag{$tag[$#tag]}=-1; 335276479Sdim } else { 336218885Sdim $tag{$tag[$#tag]}=0; 337218885Sdim } 338280031Sdim pop(@tag); 339280031Sdim } elsif (/^\#\s*else/) { 340218885Sdim my $t=$tag[$#tag]; 341280031Sdim $tag{$t}= -$tag{$t}; 342280031Sdim } elsif (/^\#\s*if\s+1/) { 343218885Sdim # Dummy tag 344280031Sdim push(@tag,"TRUE"); 345218885Sdim $tag{"TRUE"}=1; 346280031Sdim } elsif (/^\#\s*if\s+0/) { 347261991Sdim # Dummy tag 348276479Sdim push(@tag,"TRUE"); 349276479Sdim $tag{"TRUE"}=-1; 350276479Sdim } elsif (/^\#\s*define\s+(\w+)\s+(\w+)/ 351288943Sdim && $symhacking) { 352280031Sdim my $s = $1; 353280031Sdim my $a = 354218885Sdim $2.":".join(",", grep(!/^$/, 355280031Sdim map { $tag{$_} == 1 ? 356280031Sdim $_ : "" } 357218885Sdim @known_platforms)); 358280031Sdim $rename{$s} = $a; 359261991Sdim } 360218885Sdim if (/^\#/) { 361296417Sdim my @p = grep(!/^$/, 362296417Sdim map { $tag{$_} == 1 ? $_ : 363296417Sdim $tag{$_} == -1 ? "!".$_ : "" } 364296417Sdim @known_platforms); 365296417Sdim my @a = grep(!/^$/, 366261991Sdim map { $tag{"NO_".$_} == -1 ? $_ : "" } 367261991Sdim @known_algorithms); 368309124Sdim $def .= "#INFO:".join(',',@p).":".join(',',@a).";"; 369309124Sdim next; 370309124Sdim } 371309124Sdim if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) { 372309124Sdim next; 373309124Sdim } elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) { 374309124Sdim next; 375309124Sdim } elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) { 376309124Sdim next; 377218885Sdim } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ || 378218885Sdim /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ) { 379276479Sdim # Things not in Win16 380261991Sdim $syms{"PEM_read_${1}"} = 1; 381276479Sdim $platform{"PEM_read_${1}"} = "!WIN16"; 382276479Sdim $syms{"PEM_write_${1}"} = 1; 383276479Sdim $platform{"PEM_write_${1}"} = "!WIN16"; 384276479Sdim # Things that are everywhere 385261991Sdim $syms{"PEM_read_bio_${1}"} = 1; 386276479Sdim $syms{"PEM_write_bio_${1}"} = 1; 387261991Sdim if ($1 eq "RSAPrivateKey" || 388218885Sdim $1 eq "RSAPublicKey" || 389261991Sdim $1 eq "RSA_PUBKEY") { 390261991Sdim $algorithm{"PEM_read_${1}"} = "RSA"; 391261991Sdim $algorithm{"PEM_write_${1}"} = "RSA"; 392296417Sdim $algorithm{"PEM_read_bio_${1}"} = "RSA"; 393296417Sdim $algorithm{"PEM_write_bio_${1}"} = "RSA"; 394296417Sdim } 395296417Sdim elsif ($1 eq "DSAPrivateKey" || 396296417Sdim $1 eq "DSAparams" || 397296417Sdim $1 eq "RSA_PUBKEY") { 398218885Sdim $algorithm{"PEM_read_${1}"} = "DSA"; 399261991Sdim $algorithm{"PEM_write_${1}"} = "DSA"; 400261991Sdim $algorithm{"PEM_read_bio_${1}"} = "DSA"; 401261991Sdim $algorithm{"PEM_write_bio_${1}"} = "DSA"; 402261991Sdim } 403261991Sdim elsif ($1 eq "DHparams") { 404309124Sdim $algorithm{"PEM_read_${1}"} = "DH"; 405261991Sdim $algorithm{"PEM_write_${1}"} = "DH"; 406261991Sdim $algorithm{"PEM_read_bio_${1}"} = "DH"; 407218885Sdim $algorithm{"PEM_write_bio_${1}"} = "DH"; 408218885Sdim } 409218885Sdim } elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ || 410261991Sdim /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) { 411218885Sdim # Things not in Win16 412218885Sdim $syms{"PEM_write_${1}"} = 1; 413218885Sdim $platform{"PEM_write_${1}"} .= ",!WIN16"; 414276479Sdim # Things that are everywhere 415261991Sdim $syms{"PEM_write_bio_${1}"} = 1; 416261991Sdim if ($1 eq "RSAPrivateKey" || 417261991Sdim $1 eq "RSAPublicKey" || 418261991Sdim $1 eq "RSA_PUBKEY") { 419261991Sdim $algorithm{"PEM_write_${1}"} = "RSA"; 420261991Sdim $algorithm{"PEM_write_bio_${1}"} = "RSA"; 421261991Sdim } 422261991Sdim elsif ($1 eq "DSAPrivateKey" || 423261991Sdim $1 eq "DSAparams" || 424288943Sdim $1 eq "RSA_PUBKEY") { 425261991Sdim $algorithm{"PEM_write_${1}"} = "DSA"; 426276479Sdim $algorithm{"PEM_write_bio_${1}"} = "DSA"; 427218885Sdim } 428261991Sdim elsif ($1 eq "DHparams") { 429261991Sdim $algorithm{"PEM_write_${1}"} = "DH"; 430261991Sdim $algorithm{"PEM_write_bio_${1}"} = "DH"; 431261991Sdim } 432276479Sdim } elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ || 433261991Sdim /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) { 434261991Sdim # Things not in Win16 435276479Sdim $syms{"PEM_read_${1}"} = 1; 436261991Sdim $platform{"PEM_read_${1}"} .= ",!WIN16"; 437218885Sdim # Things that are everywhere 438261991Sdim $syms{"PEM_read_bio_${1}"} = 1; 439261991Sdim } elsif ( 440261991Sdim ($tag{'TRUE'} != -1) 441261991Sdim && ($tag{'CONST_STRICT'} != 1) 442261991Sdim ) 443261991Sdim { 444261991Sdim if (/\{|\/\*|\([^\)]*$/) { 445261991Sdim $line = $_; 446261991Sdim } else { 447309124Sdim $def .= $_; 448309124Sdim } 449309124Sdim } 450261991Sdim } 451261991Sdim close(IN); 452261991Sdim 453276479Sdim my $algs; 454218885Sdim my $plays; 455218885Sdim 456261991Sdim foreach (split /;/, $def) { 457276479Sdim my $s; my $k = "FUNCTION"; my $p; my $a; 458276479Sdim s/^[\n\s]*//g; 459276479Sdim s/[\n\s]*$//g; 460261991Sdim next if(/\#undef/); 461276479Sdim next if(/typedef\W/); 462261991Sdim next if(/\#define/); 463218885Sdim 464261991Sdim if (/^\#INFO:([^:]*):(.*)$/) { 465288943Sdim $plats = $1; 466261991Sdim $algs = $2; 467218885Sdim next; 468276479Sdim } elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+)(\[[0-9]*\])*\s*$/) { 469261991Sdim $s = $1; 470261991Sdim $k = "VARIABLE"; 471261991Sdim } elsif (/\(\*(\w*)\([^\)]+/) { 472261991Sdim $s = $1; 473261991Sdim } elsif (/\w+\W+(\w+)\W*\(\s*\)$/s) { 474261991Sdim # K&R C 475276479Sdim next; 476218885Sdim } elsif (/\w+\W+\w+\W*\(.*\)$/s) { 477218885Sdim while (not /\(\)$/s) { 478280031Sdim s/[^\(\)]*\)$/\)/s; 479261991Sdim s/\([^\(\)]*\)\)$/\)/s; 480218885Sdim } 481261991Sdim s/\(void\)//; 482261991Sdim /(\w+)\W*\(\)/s; 483261991Sdim $s = $1; 484261991Sdim } elsif (/\(/ and not (/=/)) { 485261991Sdim print STDERR "File $file: cannot parse: $_;\n"; 486261991Sdim next; 487261991Sdim } else { 488261991Sdim next; 489261991Sdim } 490261991Sdim 491261991Sdim $syms{$s} = 1; 492261991Sdim $kind{$s} = $k; 493261991Sdim 494261991Sdim $p = $plats; 495261991Sdim $a = $algs; 496261991Sdim $a .= ",BF" if($s =~ /EVP_bf/); 497218885Sdim $a .= ",CAST" if($s =~ /EVP_cast/); 498261991Sdim $a .= ",DES" if($s =~ /EVP_des/); 499261991Sdim $a .= ",DSA" if($s =~ /EVP_dss/); 500261991Sdim $a .= ",IDEA" if($s =~ /EVP_idea/); 501261991Sdim $a .= ",MD2" if($s =~ /EVP_md2/); 502261991Sdim $a .= ",MD4" if($s =~ /EVP_md4/); 503261991Sdim $a .= ",MD5" if($s =~ /EVP_md5/); 504261991Sdim $a .= ",RC2" if($s =~ /EVP_rc2/); 505261991Sdim $a .= ",RC4" if($s =~ /EVP_rc4/); 506261991Sdim $a .= ",RC5" if($s =~ /EVP_rc5/); 507218885Sdim $a .= ",RIPEMD" if($s =~ /EVP_ripemd/); 508218885Sdim $a .= ",SHA" if($s =~ /EVP_sha/); 509276479Sdim $a .= ",RSA" if($s =~ /EVP_(Open|Seal)(Final|Init)/); 510261991Sdim $a .= ",RSA" if($s =~ /PEM_Seal(Final|Init|Update)/); 511261991Sdim $a .= ",RSA" if($s =~ /RSAPrivateKey/); 512261991Sdim $a .= ",RSA" if($s =~ /SSLv23?_((client|server)_)?method/); 513261991Sdim 514314564Sdim $platform{$s} .= ','.$p; 515314564Sdim $algorithm{$s} .= ','.$a; 516261991Sdim 517261991Sdim if (defined($rename{$s})) { 518288943Sdim (my $r, my $p) = split(/:/,$rename{$s}); 519276479Sdim my @ip = map { /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p; 520261991Sdim $syms{$r} = 1; 521261991Sdim $kind{$r} = $kind{$s}."(".$s.")"; 522280031Sdim $algorithm{$r} = $algorithm{$s}; 523280031Sdim $platform{$r} = $platform{$s}.",".$p; 524261991Sdim $platform{$s} .= ','.join(',', @ip).','.join(',', @ip); 525280031Sdim } 526261991Sdim } 527261991Sdim } 528280031Sdim 529280031Sdim # Prune the returned symbols 530280031Sdim 531280031Sdim $platform{"crypt"} .= ",!PERL5,!__FreeBSD__,!NeXT"; 532261991Sdim 533261991Sdim delete $syms{"SSL_add_dir_cert_subjects_to_stack"}; 534261991Sdim delete $syms{"bn_dump1"}; 535261991Sdim 536261991Sdim $platform{"BIO_s_file_internal"} .= ",WIN16"; 537218885Sdim $platform{"BIO_new_file_internal"} .= ",WIN16"; 538218885Sdim $platform{"BIO_new_fp_internal"} .= ",WIN16"; 539280031Sdim 540261991Sdim $platform{"BIO_s_file"} .= ",!WIN16"; 541261991Sdim $platform{"BIO_new_file"} .= ",!WIN16"; 542261991Sdim $platform{"BIO_new_fp"} .= ",!WIN16"; 543261991Sdim 544261991Sdim $platform{"BIO_s_log"} .= ",!WIN32,!WIN16,!macintosh"; 545288943Sdim 546261991Sdim if(exists $syms{"ERR_load_CRYPTO_strings"}) { 547218885Sdim $platform{"ERR_load_CRYPTO_strings"} .= ",!VMS,!WIN16"; 548218885Sdim $syms{"ERR_load_CRYPTOlib_strings"} = 1; 549261991Sdim $platform{"ERR_load_CRYPTOlib_strings"} .= ",VMS,WIN16"; 550261991Sdim } 551261991Sdim 552261991Sdim # Info we know about 553261991Sdim 554261991Sdim $platform{"RSA_PKCS1_RSAref"} = "RSAREF"; 555261991Sdim $algorithm{"RSA_PKCS1_RSAref"} = "RSA"; 556261991Sdim 557261991Sdim push @ret, map { $_."\\".&info_string($_,"EXIST", 558261991Sdim $platform{$_}, 559261991Sdim $kind{$_}, 560261991Sdim $algorithm{$_}) } keys %syms; 561288943Sdim 562261991Sdim return(@ret); 563261991Sdim} 564261991Sdim 565261991Sdimsub info_string { 566261991Sdim (my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_; 567261991Sdim 568261991Sdim my %a = defined($algorithms) ? 569261991Sdim map { $_ => 1 } split /,/, $algorithms : (); 570288943Sdim my $pl = defined($platforms) ? $platforms : ""; 571261991Sdim my %p = map { $_ => 0 } split /,/, $pl; 572261991Sdim my $k = defined($kind) ? $kind : "FUNCTION"; 573261991Sdim my $ret; 574218885Sdim 575261991Sdim # We do this, because if there's code like the following, it really 576218885Sdim # means the function exists in all cases and should therefore be 577218885Sdim # everywhere. By increasing and decreasing, we may attain 0: 578261991Sdim # 579261991Sdim # ifndef WIN16 580261991Sdim # int foo(); 581276479Sdim # else 582218885Sdim # int _fat foo(); 583218885Sdim # endif 584280031Sdim foreach $platform (split /,/, $pl) { 585280031Sdim if ($platform =~ /^!(.*)$/) { 586280031Sdim $p{$1}--; 587280031Sdim } else { 588280031Sdim $p{$platform}++; 589280031Sdim } 590261991Sdim } 591218885Sdim foreach $platform (keys %p) { 592261991Sdim if ($p{$platform} == 0) { delete $p{$platform}; } 593261991Sdim } 594261991Sdim 595261991Sdim delete $p{""}; 596218885Sdim delete $a{""}; 597261991Sdim 598261991Sdim $ret = $exist; 599261991Sdim $ret .= ":".join(',',map { $p{$_} < 0 ? "!".$_ : $_ } keys %p); 600261991Sdim $ret .= ":".$k; 601218885Sdim $ret .= ":".join(',',keys %a); 602261991Sdim return $ret; 603261991Sdim} 604261991Sdim 605261991Sdimsub maybe_add_info { 606218885Sdim (my $name, *nums, my @symbols) = @_; 607261991Sdim my $sym; 608261991Sdim my $new_info = 0; 609261991Sdim 610261991Sdim print STDERR "Updating $name info\n"; 611218885Sdim foreach $sym (@symbols) { 612261991Sdim (my $s, my $i) = split /\\/, $sym; 613261991Sdim $i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/; 614261991Sdim if (defined($nums{$s})) { 615261991Sdim (my $n, my $dummy) = split /\\/, $nums{$s}; 616261991Sdim if (!defined($dummy) || $i ne $dummy) { 617218885Sdim $nums{$s} = $n."\\".$i; 618276479Sdim $new_info++; 619261991Sdim #print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n"; 620261991Sdim } 621218885Sdim } 622280031Sdim } 623261991Sdim if ($new_info) { 624218885Sdim print STDERR "$new_info old symbols got an info update\n"; 625261991Sdim if (!$do_rewrite) { 626261991Sdim print STDERR "You should do a rewrite to fix this.\n"; 627261991Sdim } 628261991Sdim } else { 629261991Sdim print STDERR "No old symbols needed info update\n"; 630261991Sdim } 631261991Sdim} 632261991Sdim 633261991Sdimsub print_test_file 634218885Sdim{ 635261991Sdim (*OUT,my $name,*nums,my @symbols)=@_; 636261991Sdim my $n = 1; my @e; my @r; 637261991Sdim my $sym; my $prev = ""; my $prefSSLeay; 638261991Sdim 639288943Sdim (@e)=grep(/^SSLeay\\.*?:.*?:FUNCTION/,@symbols); 640218885Sdim (@r)=grep(/^\w+\\.*?:.*?:FUNCTION/ && !/^SSLeay\\.*?:.*?:FUNCTION/,@symbols); 641261991Sdim @symbols=((sort @e),(sort @r)); 642261991Sdim 643261991Sdim foreach $sym (@symbols) { 644261991Sdim (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/; 645261991Sdim if ($s ne $prev) { 646276479Sdim if (!defined($nums{$sym})) { 647261991Sdim printf STDERR "Warning: $sym does not have a number assigned\n" 648276479Sdim if(!$do_update); 649261991Sdim } else { 650288943Sdim $n=$nums{$s}; 651261991Sdim print OUT "\t$s();\n"; 652261991Sdim } 653218885Sdim } 654261991Sdim $prev = $s; # To avoid duplicates... 655261991Sdim } 656276479Sdim} 657276479Sdim 658276479Sdimsub print_def_file 659261991Sdim{ 660218885Sdim (*OUT,my $name,*nums,my @symbols)=@_; 661261991Sdim my $n = 1; my @e; my @r; 662261991Sdim 663288943Sdim if ($W32) 664288943Sdim { $name.="32"; } 665218885Sdim else 666276479Sdim { $name.="16"; } 667218885Sdim 668218885Sdim print OUT <<"EOF"; 669276479Sdim; 670261991Sdim; Definition file for the DLL version of the $name library from OpenSSL 671261991Sdim; 672261991Sdim 673261991SdimLIBRARY $name 674261991Sdim 675276479SdimDESCRIPTION 'OpenSSL $name - http://www.openssl.org/' 676261991Sdim 677218885SdimEOF 678276479Sdim 679261991Sdim if (!$W32) { 680261991Sdim print <<"EOF"; 681276479SdimCODE PRELOAD MOVEABLE 682261991SdimDATA PRELOAD MOVEABLE SINGLE 683276479Sdim 684261991SdimEXETYPE WINDOWS 685288943Sdim 686261991SdimHEAPSIZE 4096 687218885SdimSTACKSIZE 8192 688261991Sdim 689261991SdimEOF 690261991Sdim } 691261991Sdim 692261991Sdim print "EXPORTS\n"; 693218885Sdim 694261991Sdim (@e)=grep(/^SSLeay\\.*?:.*?:FUNCTION/,@symbols); 695276479Sdim (@r)=grep(/^\w+\\.*?:.*?:FUNCTION/ && !/^SSLeay\\.*?:.*?:FUNCTION/,@symbols); 696276479Sdim @symbols=((sort @e),(sort @r)); 697276479Sdim 698261991Sdim 699218885Sdim foreach $sym (@symbols) { 700261991Sdim (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/; 701276479Sdim if (!defined($nums{$s})) { 702218885Sdim printf STDERR "Warning: $s does not have a number assigned\n" 703218885Sdim if(!$do_update); 704309124Sdim } else { 705309124Sdim (my $n, my $i) = split /\\/, $nums{$s}; 706261991Sdim my %pf = (); 707218885Sdim my @p = split(/,/, ($i =~ /^[^:]*:([^:]*):/,$1)); 708280031Sdim my @a = split(/,/, ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1)); 709261991Sdim # @p_purged must contain hardware platforms only 710218885Sdim my @p_purged = (); 711296417Sdim foreach $ptmp (@p) { 712296417Sdim next if $ptmp =~ /^!?RSAREF$/; 713296417Sdim push @p_purged, $ptmp; 714296417Sdim } 715261991Sdim my $negatives = !!grep(/^!/,@p); 716276479Sdim # It is very important to check NT before W32 717288943Sdim if ((($NT && (!@p_purged 718261991Sdim || (!$negatives && grep(/^WINNT$/,@p)) 719261991Sdim || ($negatives && !grep(/^!WINNT$/,@p)))) 720261991Sdim || ($W32 && (!@p_purged 721276479Sdim || (!$negatives && grep(/^WIN32$/,@p)) 722261991Sdim || ($negatives && !grep(/^!WIN32$/,@p)))) 723261991Sdim || ($W16 && (!@p_purged 724276479Sdim || (!$negatives && grep(/^WIN16$/,@p)) 725261991Sdim || ($negatives && !grep(/^!WIN16$/,@p))))) 726218885Sdim && (!@p 727218885Sdim || (!$negatives 728261991Sdim && ($rsaref || !grep(/^RSAREF$/,@p))) 729261991Sdim || ($negatives 730261991Sdim && (!$rsaref || !grep(/^!RSAREF$/,@p)))) 731288943Sdim && (!@a || (!$no_rc2 || !grep(/^RC2$/,@a))) 732218885Sdim && (!@a || (!$no_rc4 || !grep(/^RC4$/,@a))) 733218885Sdim && (!@a || (!$no_rc5 || !grep(/^RC5$/,@a))) 734309124Sdim && (!@a || (!$no_idea || !grep(/^IDEA$/,@a))) 735309124Sdim && (!@a || (!$no_des || !grep(/^DES$/,@a))) 736309124Sdim && (!@a || (!$no_bf || !grep(/^BF$/,@a))) 737309124Sdim && (!@a || (!$no_cast || !grep(/^CAST$/,@a))) 738309124Sdim && (!@a || (!$no_md2 || !grep(/^MD2$/,@a))) 739309124Sdim && (!@a || (!$no_md4 || !grep(/^MD4$/,@a))) 740309124Sdim && (!@a || (!$no_md5 || !grep(/^MD5$/,@a))) 741309124Sdim && (!@a || (!$no_sha || !grep(/^SHA$/,@a))) 742309124Sdim && (!@a || (!$no_ripemd || !grep(/^RIPEMD$/,@a))) 743309124Sdim && (!@a || (!$no_mdc2 || !grep(/^MDC2$/,@a))) 744309124Sdim && (!@a || (!$no_rsa || !grep(/^RSA$/,@a))) 745309124Sdim && (!@a || (!$no_dsa || !grep(/^DSA$/,@a))) 746309124Sdim && (!@a || (!$no_dh || !grep(/^DH$/,@a))) 747309124Sdim && (!@a || (!$no_hmac || !grep(/^HMAC$/,@a))) 748309124Sdim && (!@a || (!$no_fp_api || !grep(/^FP_API$/,@a))) 749309124Sdim ) { 750261991Sdim printf OUT " %s%-40s@%d\n",($W32)?"":"_",$s,$n; 751276479Sdim# } else { 752218885Sdim# print STDERR "DEBUG: \"$sym\" (@p):", 753218885Sdim# " rsaref:", !!(!@p 754276479Sdim# || (!$negatives 755261991Sdim# && ($rsaref || !grep(/^RSAREF$/,@p))) 756261991Sdim# || ($negatives 757261991Sdim# && (!$rsaref || !grep(/^!RSAREF$/,@p))))?1:0, 758261991Sdim# " 16:", !!($W16 && (!@p_purged 759218885Sdim# || (!$negatives && grep(/^WIN16$/,@p)) 760261991Sdim# || ($negatives && !grep(/^!WIN16$/,@p)))), 761218885Sdim# " 32:", !!($W32 && (!@p_purged 762280031Sdim# || (!$negatives && grep(/^WIN32$/,@p)) 763261991Sdim# || ($negatives && !grep(/^!WIN32$/,@p)))), 764218885Sdim# " NT:", !!($NT && (!@p_purged 765261991Sdim# || (!$negatives && grep(/^WINNT$/,@p)) 766261991Sdim# || ($negatives && !grep(/^!WINNT$/,@p)))), 767261991Sdim# "\n"; 768261991Sdim } 769261991Sdim } 770261991Sdim } 771261991Sdim printf OUT "\n"; 772261991Sdim} 773276479Sdim 774276479Sdimsub load_numbers 775276479Sdim{ 776276479Sdim my($name)=@_; 777276479Sdim my(@a,%ret); 778261991Sdim 779261991Sdim $max_num = 0; 780261991Sdim $num_noinfo = 0; 781261991Sdim $prev = ""; 782276479Sdim 783288943Sdim open(IN,"<$name") || die "unable to open $name:$!\n"; 784261991Sdim while (<IN>) { 785261991Sdim chop; 786261991Sdim s/#.*$//; 787276479Sdim next if /^\s*$/; 788261991Sdim @a=split; 789261991Sdim if (defined $ret{$a[0]}) { 790276479Sdim print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n"; 791261991Sdim } 792221345Sdim if ($max_num > $a[1]) { 793218885Sdim print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n"; 794261991Sdim } 795261991Sdim if ($max_num == $a[1]) { 796261991Sdim # This is actually perfectly OK 797218885Sdim #print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n"; 798276479Sdim } 799261991Sdim if ($#a < 2) { 800218885Sdim # Existence will be proven later, in do_defs 801261991Sdim $ret{$a[0]}=$a[1]; 802261991Sdim $num_noinfo++; 803261991Sdim } else { 804288943Sdim $ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker 805261991Sdim } 806218885Sdim $max_num = $a[1] if $a[1] > $max_num; 807261991Sdim $prev=$a[0]; 808276479Sdim } 809218885Sdim if ($num_noinfo) { 810309124Sdim print STDERR "Warning: $num_noinfo symbols were without info."; 811309124Sdim if ($do_rewrite) { 812309124Sdim printf STDERR " The rewrite will fix this.\n"; 813309124Sdim } else { 814309124Sdim printf STDERR " You should do a rewrite to fix this.\n"; 815309124Sdim } 816309124Sdim } 817309124Sdim close(IN); 818309124Sdim return(%ret); 819309124Sdim} 820309124Sdim 821309124Sdimsub parse_number 822309124Sdim{ 823309124Sdim (my $str, my $what) = @_; 824309124Sdim (my $n, my $i) = split(/\\/,$str); 825309124Sdim if ($what eq "n") { 826309124Sdim return $n; 827309124Sdim } else { 828309124Sdim return $i; 829309124Sdim } 830309124Sdim} 831309124Sdim 832309124Sdimsub rewrite_numbers 833309124Sdim{ 834309124Sdim (*OUT,$name,*nums,@symbols)=@_; 835309124Sdim my $thing; 836309124Sdim 837309124Sdim print STDERR "Rewriting $name\n"; 838309124Sdim 839309124Sdim my @r = grep(/^\w+\\.*?:.*?:\w+\(\w+\)/,@symbols); 840309124Sdim my $r; my %r; my %rsyms; 841309124Sdim foreach $r (@r) { 842309124Sdim (my $s, my $i) = split /\\/, $r; 843309124Sdim my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/; 844309124Sdim $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/; 845309124Sdim $r{$a} = $s."\\".$i; 846261991Sdim $rsyms{$s} = 1; 847218885Sdim } 848276479Sdim 849296417Sdim my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums; 850296417Sdim foreach $sym (@s) { 851296417Sdim (my $n, my $i) = split /\\/, $nums{$sym}; 852296417Sdim next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/; 853276479Sdim next if defined($rsyms{$sym}); 854276479Sdim $i="NOEXIST::FUNCTION:" if !defined($i) || $i eq ""; 855296417Sdim printf OUT "%s%-40s%d\t%s\n","",$sym,$n,$i; 856296417Sdim if (exists $r{$sym}) { 857296417Sdim (my $s, $i) = split /\\/,$r{$sym}; 858296417Sdim printf OUT "%s%-40s%d\t%s\n","",$s,$n,$i; 859276479Sdim } 860296417Sdim } 861296417Sdim} 862276479Sdim 863276479Sdimsub update_numbers 864296417Sdim{ 865296417Sdim (*OUT,$name,*nums,my $start_num, my @symbols)=@_; 866296417Sdim my $new_syms = 0; 867280031Sdim 868296417Sdim print STDERR "Updating $name numbers\n"; 869280031Sdim 870280031Sdim my @r = grep(/^\w+\\.*?:.*?:\w+\(\w+\)/,@symbols); 871280031Sdim my $r; my %r; my %rsyms; 872280031Sdim foreach $r (@r) { 873296417Sdim (my $s, my $i) = split /\\/, $r; 874280031Sdim my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/; 875280031Sdim $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/; 876280031Sdim $r{$a} = $s."\\".$i; 877280031Sdim $rsyms{$s} = 1; 878280031Sdim } 879280031Sdim 880280031Sdim foreach $sym (@symbols) { 881296417Sdim (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/; 882280031Sdim next if $i =~ /^.*?:.*?:\w+\(\w+\)/; 883280031Sdim next if defined($rsyms{$sym}); 884280031Sdim die "ERROR: Symbol $sym had no info attached to it." 885296417Sdim if $i eq ""; 886296417Sdim if (!exists $nums{$s}) { 887280031Sdim $new_syms++; 888280031Sdim printf OUT "%s%-40s%d\t%s\n","",$s, ++$start_num,$i; 889280031Sdim if (exists $r{$s}) { 890280031Sdim ($s, $i) = split /\\/,$r{$s}; 891280031Sdim printf OUT "%s%-40s%d\t%s\n","",$s, $start_num,$i; 892280031Sdim } 893280031Sdim } 894280031Sdim } 895280031Sdim if($new_syms) { 896280031Sdim print STDERR "$new_syms New symbols added\n"; 897296417Sdim } else { 898296417Sdim print STDERR "No New symbols Added\n"; 899296417Sdim } 900296417Sdim} 901296417Sdim 902296417Sdimsub check_existing 903296417Sdim{ 904296417Sdim (*nums, my @symbols)=@_; 905280031Sdim my %existing; my @remaining; 906296417Sdim @remaining=(); 907280031Sdim foreach $sym (@symbols) { 908280031Sdim (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/; 909296417Sdim $existing{$s}=1; 910280031Sdim } 911280031Sdim foreach $sym (keys %nums) { 912276479Sdim if (!exists $existing{$sym}) { 913276479Sdim push @remaining, $sym; 914261991Sdim } 915276479Sdim } 916276479Sdim if(@remaining) { 917276479Sdim print STDERR "The following symbols do not seem to exist:\n"; 918276479Sdim foreach $sym (@remaining) { 919276479Sdim print STDERR "\t",$sym,"\n"; 920261991Sdim } 921276479Sdim } 922288943Sdim} 923261991Sdim 924276479Sdim