mkdef.pl revision 55714
155714Skris#!/usr/local/bin/perl -w 255714Skris# 355714Skris# generate a .def file 455714Skris# 555714Skris# It does this by parsing the header files and looking for the 655714Skris# prototyped functions: it then prunes the output. 755714Skris# 855714Skris 955714Skris$crypto_num="util/libeay.num"; 1055714Skris$ssl_num= "util/ssleay.num"; 1155714Skris 1255714Skrismy $do_update = 0; 1355714Skrismy $do_crypto = 0; 1455714Skrismy $do_ssl = 0; 1555714Skris$rsaref = 0; 1655714Skris 1755714Skris$W32=1; 1855714Skris$NT=0; 1955714Skris# Set this to make typesafe STACK definitions appear in DEF 2055714Skris$safe_stack_def = 1; 2155714Skris 2255714Skris$options=""; 2355714Skrisopen(IN,"<Makefile.ssl") || die "unable to open Makefile.ssl!\n"; 2455714Skriswhile(<IN>) { 2555714Skris $options=$1 if (/^OPTIONS=(.*)$/); 2655714Skris} 2755714Skrisclose(IN); 2855714Skris 2955714Skrisforeach (@ARGV, split(/ /, $options)) 3055714Skris { 3155714Skris $W32=1 if $_ eq "32"; 3255714Skris $W32=0 if $_ eq "16"; 3355714Skris if($_ eq "NT") { 3455714Skris $W32 = 1; 3555714Skris $NT = 1; 3655714Skris } 3755714Skris $do_ssl=1 if $_ eq "ssleay"; 3855714Skris $do_ssl=1 if $_ eq "ssl"; 3955714Skris $do_crypto=1 if $_ eq "libeay"; 4055714Skris $do_crypto=1 if $_ eq "crypto"; 4155714Skris $do_update=1 if $_ eq "update"; 4255714Skris $rsaref=1 if $_ eq "rsaref"; 4355714Skris 4455714Skris if (/^no-rc2$/) { $no_rc2=1; } 4555714Skris elsif (/^no-rc4$/) { $no_rc4=1; } 4655714Skris elsif (/^no-rc5$/) { $no_rc5=1; } 4755714Skris elsif (/^no-idea$/) { $no_idea=1; } 4855714Skris elsif (/^no-des$/) { $no_des=1; } 4955714Skris elsif (/^no-bf$/) { $no_bf=1; } 5055714Skris elsif (/^no-cast$/) { $no_cast=1; } 5155714Skris elsif (/^no-md2$/) { $no_md2=1; } 5255714Skris elsif (/^no-md5$/) { $no_md5=1; } 5355714Skris elsif (/^no-sha$/) { $no_sha=1; } 5455714Skris elsif (/^no-ripemd$/) { $no_ripemd=1; } 5555714Skris elsif (/^no-mdc2$/) { $no_mdc2=1; } 5655714Skris elsif (/^no-rsa$/) { $no_rsa=1; } 5755714Skris elsif (/^no-dsa$/) { $no_dsa=1; } 5855714Skris elsif (/^no-dh$/) { $no_dh=1; } 5955714Skris elsif (/^no-hmac$/) { $no_hmac=1; } 6055714Skris } 6155714Skris 6255714Skrisif (!$do_ssl && !$do_crypto) 6355714Skris { 6455714Skris print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT ] [rsaref]\n"; 6555714Skris exit(1); 6655714Skris } 6755714Skris 6855714Skris%ssl_list=&load_numbers($ssl_num); 6955714Skris$max_ssl = $max_num; 7055714Skris%crypto_list=&load_numbers($crypto_num); 7155714Skris$max_crypto = $max_num; 7255714Skris 7355714Skris$ssl="ssl/ssl.h"; 7455714Skris 7555714Skris$crypto ="crypto/crypto.h"; 7655714Skris$crypto.=" crypto/des/des.h" unless $no_des; 7755714Skris$crypto.=" crypto/idea/idea.h" unless $no_idea; 7855714Skris$crypto.=" crypto/rc4/rc4.h" unless $no_rc4; 7955714Skris$crypto.=" crypto/rc5/rc5.h" unless $no_rc5; 8055714Skris$crypto.=" crypto/rc2/rc2.h" unless $no_rc2; 8155714Skris$crypto.=" crypto/bf/blowfish.h" unless $no_bf; 8255714Skris$crypto.=" crypto/cast/cast.h" unless $no_cast; 8355714Skris$crypto.=" crypto/md2/md2.h" unless $no_md2; 8455714Skris$crypto.=" crypto/md5/md5.h" unless $no_md5; 8555714Skris$crypto.=" crypto/mdc2/mdc2.h" unless $no_mdc2; 8655714Skris$crypto.=" crypto/sha/sha.h" unless $no_sha; 8755714Skris$crypto.=" crypto/ripemd/ripemd.h" unless $no_ripemd; 8855714Skris 8955714Skris$crypto.=" crypto/bn/bn.h"; 9055714Skris$crypto.=" crypto/rsa/rsa.h" unless $no_rsa; 9155714Skris$crypto.=" crypto/dsa/dsa.h" unless $no_dsa; 9255714Skris$crypto.=" crypto/dh/dh.h" unless $no_dh; 9355714Skris$crypto.=" crypto/hmac/hmac.h" unless $no_hmac; 9455714Skris 9555714Skris$crypto.=" crypto/stack/stack.h"; 9655714Skris$crypto.=" crypto/buffer/buffer.h"; 9755714Skris$crypto.=" crypto/bio/bio.h"; 9855714Skris$crypto.=" crypto/lhash/lhash.h"; 9955714Skris$crypto.=" crypto/conf/conf.h"; 10055714Skris$crypto.=" crypto/txt_db/txt_db.h"; 10155714Skris 10255714Skris$crypto.=" crypto/evp/evp.h"; 10355714Skris$crypto.=" crypto/objects/objects.h"; 10455714Skris$crypto.=" crypto/pem/pem.h"; 10555714Skris#$crypto.=" crypto/meth/meth.h"; 10655714Skris$crypto.=" crypto/asn1/asn1.h"; 10755714Skris$crypto.=" crypto/asn1/asn1_mac.h"; 10855714Skris$crypto.=" crypto/err/err.h"; 10955714Skris$crypto.=" crypto/pkcs7/pkcs7.h"; 11055714Skris$crypto.=" crypto/pkcs12/pkcs12.h"; 11155714Skris$crypto.=" crypto/x509/x509.h"; 11255714Skris$crypto.=" crypto/x509/x509_vfy.h"; 11355714Skris$crypto.=" crypto/x509v3/x509v3.h"; 11455714Skris$crypto.=" crypto/rand/rand.h"; 11555714Skris$crypto.=" crypto/comp/comp.h"; 11655714Skris$crypto.=" crypto/tmdiff.h"; 11755714Skris 11855714Skris@ssl_func = &do_defs("SSLEAY", $ssl); 11955714Skris@crypto_func = &do_defs("LIBEAY", $crypto); 12055714Skris 12155714Skris 12255714Skrisif ($do_update) { 12355714Skris 12455714Skrisif ($do_ssl == 1) { 12555714Skris open(OUT, ">>$ssl_num"); 12655714Skris &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl, @ssl_func); 12755714Skris close OUT; 12855714Skris} 12955714Skris 13055714Skrisif($do_crypto == 1) { 13155714Skris open(OUT, ">>$crypto_num"); 13255714Skris &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto, @crypto_func); 13355714Skris close OUT; 13455714Skris} 13555714Skris 13655714Skris} else { 13755714Skris 13855714Skris &print_def_file(*STDOUT,"SSLEAY",*ssl_list,@ssl_func) 13955714Skris if $do_ssl == 1; 14055714Skris 14155714Skris &print_def_file(*STDOUT,"LIBEAY",*crypto_list,@crypto_func) 14255714Skris if $do_crypto == 1; 14355714Skris 14455714Skris} 14555714Skris 14655714Skris 14755714Skrissub do_defs 14855714Skris{ 14955714Skris my($name,$files)=@_; 15055714Skris my @ret; 15155714Skris my %funcs; 15255714Skris 15355714Skris foreach $file (split(/\s+/,$files)) 15455714Skris { 15555714Skris open(IN,"<$file") || die "unable to open $file:$!\n"; 15655714Skris 15755714Skris my $line = "", $def= ""; 15855714Skris my %tag = ( 15955714Skris FreeBSD => 0, 16055714Skris NOPROTO => 0, 16155714Skris WIN16 => 0, 16255714Skris PERL5 => 0, 16355714Skris _WINDLL => 0, 16455714Skris NO_FP_API => 0, 16555714Skris CONST_STRICT => 0, 16655714Skris TRUE => 1, 16755714Skris ); 16855714Skris while(<IN>) { 16955714Skris last if (/BEGIN ERROR CODES/); 17055714Skris if ($line ne '') { 17155714Skris $_ = $line . $_; 17255714Skris $line = ''; 17355714Skris } 17455714Skris 17555714Skris if (/\\$/) { 17655714Skris $line = $_; 17755714Skris next; 17855714Skris } 17955714Skris 18055714Skris $cpp = 1 if /^#.*ifdef.*cplusplus/; 18155714Skris if ($cpp) { 18255714Skris $cpp = 0 if /^#.*endif/; 18355714Skris next; 18455714Skris } 18555714Skris 18655714Skris s/\/\*.*?\*\///gs; # ignore comments 18755714Skris s/{[^{}]*}//gs; # ignore {} blocks 18855714Skris if (/^\#\s*ifndef (.*)/) { 18955714Skris push(@tag,$1); 19055714Skris $tag{$1}=-1; 19155714Skris next; 19255714Skris } elsif (/^\#\s*if !defined\(([^\)]+)\)/) { 19355714Skris push(@tag,$1); 19455714Skris $tag{$1}=-1; 19555714Skris next; 19655714Skris } elsif (/^\#\s*ifdef (.*)/) { 19755714Skris push(@tag,$1); 19855714Skris $tag{$1}=1; 19955714Skris next; 20055714Skris } elsif (/^\#\s*if defined(.*)/) { 20155714Skris push(@tag,$1); 20255714Skris $tag{$1}=1; 20355714Skris next; 20455714Skris } elsif (/^\#\s*endif/) { 20555714Skris $tag{$tag[$#tag]}=0; 20655714Skris pop(@tag); 20755714Skris next; 20855714Skris } elsif (/^\#\s*else/) { 20955714Skris my $t=$tag[$#tag]; 21055714Skris $tag{$t}= -$tag{$t}; 21155714Skris next; 21255714Skris } elsif (/^\#\s*if\s+1/) { 21355714Skris # Dummy tag 21455714Skris push(@tag,"TRUE"); 21555714Skris $tag{"TRUE"}=1; 21655714Skris next; 21755714Skris } elsif (/^\#/) { 21855714Skris next; 21955714Skris } 22055714Skris if ($safe_stack_def && 22155714Skris /^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) { 22255714Skris $funcs{"sk_${1}_new"} = 1; 22355714Skris $funcs{"sk_${1}_new_null"} = 1; 22455714Skris $funcs{"sk_${1}_free"} = 1; 22555714Skris $funcs{"sk_${1}_num"} = 1; 22655714Skris $funcs{"sk_${1}_value"} = 1; 22755714Skris $funcs{"sk_${1}_set"} = 1; 22855714Skris $funcs{"sk_${1}_zero"} = 1; 22955714Skris $funcs{"sk_${1}_push"} = 1; 23055714Skris $funcs{"sk_${1}_unshift"} = 1; 23155714Skris $funcs{"sk_${1}_find"} = 1; 23255714Skris $funcs{"sk_${1}_delete"} = 1; 23355714Skris $funcs{"sk_${1}_delete_ptr"} = 1; 23455714Skris $funcs{"sk_${1}_insert"} = 1; 23555714Skris $funcs{"sk_${1}_set_cmp_func"} = 1; 23655714Skris $funcs{"sk_${1}_dup"} = 1; 23755714Skris $funcs{"sk_${1}_pop_free"} = 1; 23855714Skris $funcs{"sk_${1}_shift"} = 1; 23955714Skris $funcs{"sk_${1}_pop"} = 1; 24055714Skris $funcs{"sk_${1}_sort"} = 1; 24155714Skris } elsif ($safe_stack_def && 24255714Skris /^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) { 24355714Skris $funcs{"d2i_ASN1_SET_OF_${1}"} = 1; 24455714Skris $funcs{"i2d_ASN1_SET_OF_${1}"} = 1; 24555714Skris } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ || 24655714Skris /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ) { 24755714Skris if($W32) { 24855714Skris $funcs{"PEM_read_${1}"} = 1; 24955714Skris $funcs{"PEM_write_${1}"} = 1; 25055714Skris } 25155714Skris $funcs{"PEM_read_bio_${1}"} = 1; 25255714Skris $funcs{"PEM_write_bio_${1}"} = 1; 25355714Skris } elsif ( 25455714Skris ($tag{'FreeBSD'} != 1) && 25555714Skris ($tag{'CONST_STRICT'} != 1) && 25655714Skris (($W32 && ($tag{'WIN16'} != 1)) || 25755714Skris (!$W32 && ($tag{'WIN16'} != -1))) && 25855714Skris ($tag{'PERL5'} != 1) && 25955714Skris# ($tag{'_WINDLL'} != -1) && 26055714Skris ((!$W32 && $tag{'_WINDLL'} != -1) || 26155714Skris ($W32 && $tag{'_WINDLL'} != 1)) && 26255714Skris ((($tag{'NO_FP_API'} != 1) && $W32) || 26355714Skris (($tag{'NO_FP_API'} != -1) && !$W32))) 26455714Skris { 26555714Skris if (/{|\/\*/) { # } 26655714Skris $line = $_; 26755714Skris } else { 26855714Skris $def .= $_; 26955714Skris } 27055714Skris } 27155714Skris } 27255714Skris close(IN); 27355714Skris 27455714Skris foreach (split /;/, $def) { 27555714Skris s/^[\n\s]*//g; 27655714Skris s/[\n\s]*$//g; 27755714Skris next if(/typedef\W/); 27855714Skris next if(/EVP_bf/ and $no_bf); 27955714Skris next if(/EVP_cast/ and $no_cast); 28055714Skris next if(/EVP_des/ and $no_des); 28155714Skris next if(/EVP_dss/ and $no_dsa); 28255714Skris next if(/EVP_idea/ and $no_idea); 28355714Skris next if(/EVP_md2/ and $no_md2); 28455714Skris next if(/EVP_md5/ and $no_md5); 28555714Skris next if(/EVP_rc2/ and $no_rc2); 28655714Skris next if(/EVP_rc4/ and $no_rc4); 28755714Skris next if(/EVP_rc5/ and $no_rc5); 28855714Skris next if(/EVP_ripemd/ and $no_ripemd); 28955714Skris next if(/EVP_sha/ and $no_sha); 29055714Skris if (/\(\*(\w*)\([^\)]+/) { 29155714Skris $funcs{$1} = 1; 29255714Skris } elsif (/\w+\W+(\w+)\W*\(\s*\)$/s) { 29355714Skris # K&R C 29455714Skris next; 29555714Skris } elsif (/\w+\W+\w+\W*\(.*\)$/s) { 29655714Skris while (not /\(\)$/s) { 29755714Skris s/[^\(\)]*\)$/\)/s; 29855714Skris s/\([^\(\)]*\)\)$/\)/s; 29955714Skris } 30055714Skris s/\(void\)//; 30155714Skris /(\w+)\W*\(\)/s; 30255714Skris $funcs{$1} = 1; 30355714Skris } elsif (/\(/ and not (/=/)) { 30455714Skris print STDERR "File $file: cannot parse: $_;\n"; 30555714Skris } 30655714Skris } 30755714Skris } 30855714Skris 30955714Skris # Prune the returned functions 31055714Skris 31155714Skris delete $funcs{"SSL_add_dir_cert_subjects_to_stack"}; 31255714Skris delete $funcs{"des_crypt"}; 31355714Skris delete $funcs{"RSA_PKCS1_RSAref"} unless $rsaref; 31455714Skris 31555714Skris if($W32) { 31655714Skris delete $funcs{"BIO_s_file_internal"}; 31755714Skris delete $funcs{"BIO_new_file_internal"}; 31855714Skris delete $funcs{"BIO_new_fp_internal"}; 31955714Skris } else { 32055714Skris if(exists $funcs{"ERR_load_CRYPTO_strings"}) { 32155714Skris delete $funcs{"ERR_load_CRYPTO_strings"}; 32255714Skris $funcs{"ERR_load_CRYPTOlib_strings"} = 1; 32355714Skris } 32455714Skris delete $funcs{"BIO_s_file"}; 32555714Skris delete $funcs{"BIO_new_file"}; 32655714Skris delete $funcs{"BIO_new_fp"}; 32755714Skris } 32855714Skris if (!$NT) { 32955714Skris delete $funcs{"BIO_s_log"}; 33055714Skris } 33155714Skris 33255714Skris push @ret, keys %funcs; 33355714Skris 33455714Skris return(@ret); 33555714Skris} 33655714Skris 33755714Skrissub print_def_file 33855714Skris{ 33955714Skris (*OUT,my $name,*nums,@functions)=@_; 34055714Skris my $n =1; 34155714Skris 34255714Skris if ($W32) 34355714Skris { $name.="32"; } 34455714Skris else 34555714Skris { $name.="16"; } 34655714Skris 34755714Skris print OUT <<"EOF"; 34855714Skris; 34955714Skris; Definition file for the DLL version of the $name library from OpenSSL 35055714Skris; 35155714Skris 35255714SkrisLIBRARY $name 35355714Skris 35455714SkrisDESCRIPTION 'OpenSSL $name - http://www.openssl.org/' 35555714Skris 35655714SkrisEOF 35755714Skris 35855714Skris if (!$W32) { 35955714Skris print <<"EOF"; 36055714SkrisCODE PRELOAD MOVEABLE 36155714SkrisDATA PRELOAD MOVEABLE SINGLE 36255714Skris 36355714SkrisEXETYPE WINDOWS 36455714Skris 36555714SkrisHEAPSIZE 4096 36655714SkrisSTACKSIZE 8192 36755714Skris 36855714SkrisEOF 36955714Skris } 37055714Skris 37155714Skris print "EXPORTS\n"; 37255714Skris 37355714Skris 37455714Skris (@e)=grep(/^SSLeay/,@functions); 37555714Skris (@r)=grep(!/^SSLeay/,@functions); 37655714Skris @functions=((sort @e),(sort @r)); 37755714Skris 37855714Skris foreach $func (@functions) { 37955714Skris if (!defined($nums{$func})) { 38055714Skris printf STDERR "$func does not have a number assigned\n" 38155714Skris if(!$do_update); 38255714Skris } else { 38355714Skris $n=$nums{$func}; 38455714Skris printf OUT " %s%-40s@%d\n",($W32)?"":"_",$func,$n; 38555714Skris } 38655714Skris } 38755714Skris printf OUT "\n"; 38855714Skris} 38955714Skris 39055714Skrissub load_numbers 39155714Skris{ 39255714Skris my($name)=@_; 39355714Skris my(@a,%ret); 39455714Skris 39555714Skris $max_num = 0; 39655714Skris 39755714Skris open(IN,"<$name") || die "unable to open $name:$!\n"; 39855714Skris while (<IN>) { 39955714Skris chop; 40055714Skris s/#.*$//; 40155714Skris next if /^\s*$/; 40255714Skris @a=split; 40355714Skris $ret{$a[0]}=$a[1]; 40455714Skris $max_num = $a[1] if $a[1] > $max_num; 40555714Skris } 40655714Skris close(IN); 40755714Skris return(%ret); 40855714Skris} 40955714Skris 41055714Skrissub update_numbers 41155714Skris{ 41255714Skris (*OUT,$name,*nums,my $start_num, my @functions)=@_; 41355714Skris my $new_funcs = 0; 41455714Skris print STDERR "Updating $name\n"; 41555714Skris foreach $func (@functions) { 41655714Skris if (!exists $nums{$func}) { 41755714Skris $new_funcs++; 41855714Skris printf OUT "%s%-40s%d\n","",$func, ++$start_num; 41955714Skris } 42055714Skris } 42155714Skris if($new_funcs) { 42255714Skris print STDERR "$new_funcs New Functions added\n"; 42355714Skris } else { 42455714Skris print STDERR "No New Functions Added\n"; 42555714Skris } 42655714Skris} 427