mkdef.pl revision 59191
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
959191Skrismy $crypto_num="util/libeay.num";
1059191Skrismy $ssl_num=   "util/ssleay.num";
1155714Skris
1255714Skrismy $do_update = 0;
1355714Skrismy $do_crypto = 0;
1455714Skrismy $do_ssl = 0;
1559191Skrismy $do_ctest = 0;
1659191Skrismy $rsaref = 0;
1755714Skris
1859191Skrismy $W32=1;
1959191Skrismy $NT=0;
2055714Skris# Set this to make typesafe STACK definitions appear in DEF
2159191Skrismy $safe_stack_def = 1;
2255714Skris
2359191Skrismy $options="";
2455714Skrisopen(IN,"<Makefile.ssl") || die "unable to open Makefile.ssl!\n";
2555714Skriswhile(<IN>) {
2655714Skris    $options=$1 if (/^OPTIONS=(.*)$/);
2755714Skris}
2855714Skrisclose(IN);
2955714Skris
3059191Skris# The following ciphers may be excluded (by Configure). This means functions
3159191Skris# defined with ifndef(NO_XXX) are not included in the .def file, and everything
3259191Skris# in directory xxx is ignored.
3359191Skrismy $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
3459191Skrismy $no_cast; my $no_md2; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
3559191Skrismy $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0;
3659191Skris
3755714Skrisforeach (@ARGV, split(/ /, $options))
3855714Skris	{
3955714Skris	$W32=1 if $_ eq "32";
4055714Skris	$W32=0 if $_ eq "16";
4155714Skris	if($_ eq "NT") {
4255714Skris		$W32 = 1;
4355714Skris		$NT = 1;
4455714Skris	}
4555714Skris	$do_ssl=1 if $_ eq "ssleay";
4655714Skris	$do_ssl=1 if $_ eq "ssl";
4755714Skris	$do_crypto=1 if $_ eq "libeay";
4855714Skris	$do_crypto=1 if $_ eq "crypto";
4955714Skris	$do_update=1 if $_ eq "update";
5059191Skris	$do_ctest=1 if $_ eq "ctest";
5155714Skris	$rsaref=1 if $_ eq "rsaref";
5255714Skris
5355714Skris	if    (/^no-rc2$/)      { $no_rc2=1; }
5455714Skris	elsif (/^no-rc4$/)      { $no_rc4=1; }
5555714Skris	elsif (/^no-rc5$/)      { $no_rc5=1; }
5655714Skris	elsif (/^no-idea$/)     { $no_idea=1; }
5755714Skris	elsif (/^no-des$/)      { $no_des=1; }
5855714Skris	elsif (/^no-bf$/)       { $no_bf=1; }
5955714Skris	elsif (/^no-cast$/)     { $no_cast=1; }
6055714Skris	elsif (/^no-md2$/)      { $no_md2=1; }
6155714Skris	elsif (/^no-md5$/)      { $no_md5=1; }
6255714Skris	elsif (/^no-sha$/)      { $no_sha=1; }
6355714Skris	elsif (/^no-ripemd$/)   { $no_ripemd=1; }
6455714Skris	elsif (/^no-mdc2$/)     { $no_mdc2=1; }
6555714Skris	elsif (/^no-rsa$/)      { $no_rsa=1; }
6655714Skris	elsif (/^no-dsa$/)      { $no_dsa=1; }
6755714Skris	elsif (/^no-dh$/)       { $no_dh=1; }
6855714Skris	elsif (/^no-hmac$/)	{ $no_hmac=1; }
6955714Skris	}
7055714Skris
7159191Skris
7255714Skrisif (!$do_ssl && !$do_crypto)
7355714Skris	{
7455714Skris	print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT ] [rsaref]\n";
7555714Skris	exit(1);
7655714Skris	}
7755714Skris
7855714Skris%ssl_list=&load_numbers($ssl_num);
7955714Skris$max_ssl = $max_num;
8055714Skris%crypto_list=&load_numbers($crypto_num);
8155714Skris$max_crypto = $max_num;
8255714Skris
8359191Skrismy $ssl="ssl/ssl.h";
8455714Skris
8559191Skrismy $crypto ="crypto/crypto.h";
8655714Skris$crypto.=" crypto/des/des.h" unless $no_des;
8755714Skris$crypto.=" crypto/idea/idea.h" unless $no_idea;
8855714Skris$crypto.=" crypto/rc4/rc4.h" unless $no_rc4;
8955714Skris$crypto.=" crypto/rc5/rc5.h" unless $no_rc5;
9055714Skris$crypto.=" crypto/rc2/rc2.h" unless $no_rc2;
9155714Skris$crypto.=" crypto/bf/blowfish.h" unless $no_bf;
9255714Skris$crypto.=" crypto/cast/cast.h" unless $no_cast;
9355714Skris$crypto.=" crypto/md2/md2.h" unless $no_md2;
9455714Skris$crypto.=" crypto/md5/md5.h" unless $no_md5;
9555714Skris$crypto.=" crypto/mdc2/mdc2.h" unless $no_mdc2;
9655714Skris$crypto.=" crypto/sha/sha.h" unless $no_sha;
9755714Skris$crypto.=" crypto/ripemd/ripemd.h" unless $no_ripemd;
9855714Skris
9955714Skris$crypto.=" crypto/bn/bn.h";
10055714Skris$crypto.=" crypto/rsa/rsa.h" unless $no_rsa;
10155714Skris$crypto.=" crypto/dsa/dsa.h" unless $no_dsa;
10255714Skris$crypto.=" crypto/dh/dh.h" unless $no_dh;
10355714Skris$crypto.=" crypto/hmac/hmac.h" unless $no_hmac;
10455714Skris
10555714Skris$crypto.=" crypto/stack/stack.h";
10655714Skris$crypto.=" crypto/buffer/buffer.h";
10755714Skris$crypto.=" crypto/bio/bio.h";
10855714Skris$crypto.=" crypto/lhash/lhash.h";
10955714Skris$crypto.=" crypto/conf/conf.h";
11055714Skris$crypto.=" crypto/txt_db/txt_db.h";
11155714Skris
11255714Skris$crypto.=" crypto/evp/evp.h";
11355714Skris$crypto.=" crypto/objects/objects.h";
11455714Skris$crypto.=" crypto/pem/pem.h";
11555714Skris#$crypto.=" crypto/meth/meth.h";
11655714Skris$crypto.=" crypto/asn1/asn1.h";
11755714Skris$crypto.=" crypto/asn1/asn1_mac.h";
11855714Skris$crypto.=" crypto/err/err.h";
11955714Skris$crypto.=" crypto/pkcs7/pkcs7.h";
12055714Skris$crypto.=" crypto/pkcs12/pkcs12.h";
12155714Skris$crypto.=" crypto/x509/x509.h";
12255714Skris$crypto.=" crypto/x509/x509_vfy.h";
12355714Skris$crypto.=" crypto/x509v3/x509v3.h";
12455714Skris$crypto.=" crypto/rand/rand.h";
12555714Skris$crypto.=" crypto/comp/comp.h";
12655714Skris$crypto.=" crypto/tmdiff.h";
12755714Skris
12859191Skrismy @ssl_func = &do_defs("SSLEAY", $ssl);
12959191Skrismy @crypto_func = &do_defs("LIBEAY", $crypto);
13055714Skris
13155714Skris
13255714Skrisif ($do_update) {
13355714Skris
13455714Skrisif ($do_ssl == 1) {
13555714Skris	open(OUT, ">>$ssl_num");
13655714Skris	&update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl, @ssl_func);
13755714Skris	close OUT;
13855714Skris}
13955714Skris
14055714Skrisif($do_crypto == 1) {
14155714Skris	open(OUT, ">>$crypto_num");
14255714Skris	&update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto, @crypto_func);
14355714Skris	close OUT;
14459191Skris}
14555714Skris
14659191Skris} elsif ($do_ctest) {
14759191Skris
14859191Skris	print <<"EOF";
14959191Skris
15059191Skris/* Test file to check all DEF file symbols are present by trying
15159191Skris * to link to all of them. This is *not* intended to be run!
15259191Skris */
15359191Skris
15459191Skrisint main()
15559191Skris{
15659191SkrisEOF
15759191Skris	&print_test_file(*STDOUT,"SSLEAY",*ssl_list,@ssl_func)
15859191Skris		if $do_ssl == 1;
15959191Skris
16059191Skris	&print_test_file(*STDOUT,"LIBEAY",*crypto_list,@crypto_func)
16159191Skris		if $do_crypto == 1;
16259191Skris
16359191Skris	print "}\n";
16459191Skris
16555714Skris} else {
16655714Skris
16755714Skris	&print_def_file(*STDOUT,"SSLEAY",*ssl_list,@ssl_func)
16855714Skris		if $do_ssl == 1;
16955714Skris
17055714Skris	&print_def_file(*STDOUT,"LIBEAY",*crypto_list,@crypto_func)
17155714Skris		if $do_crypto == 1;
17255714Skris
17355714Skris}
17455714Skris
17555714Skris
17655714Skrissub do_defs
17755714Skris{
17855714Skris	my($name,$files)=@_;
17959191Skris	my $file;
18055714Skris	my @ret;
18155714Skris	my %funcs;
18259191Skris	my $cpp;
18355714Skris
18455714Skris	foreach $file (split(/\s+/,$files))
18555714Skris		{
18655714Skris		open(IN,"<$file") || die "unable to open $file:$!\n";
18759191Skris		my $line = "", my $def= "";
18855714Skris		my %tag = (
18955714Skris			FreeBSD		=> 0,
19055714Skris			NOPROTO		=> 0,
19155714Skris			WIN16		=> 0,
19255714Skris			PERL5		=> 0,
19355714Skris			_WINDLL		=> 0,
19455714Skris			NO_FP_API	=> 0,
19555714Skris			CONST_STRICT	=> 0,
19655714Skris			TRUE		=> 1,
19759191Skris			NO_RC2		=> 0,
19859191Skris			NO_RC4		=> 0,
19959191Skris			NO_RC5		=> 0,
20059191Skris			NO_IDEA		=> 0,
20159191Skris			NO_DES		=> 0,
20259191Skris			NO_BF		=> 0,
20359191Skris			NO_CAST		=> 0,
20459191Skris			NO_MD2		=> 0,
20559191Skris			NO_MD5		=> 0,
20659191Skris			NO_SHA		=> 0,
20759191Skris			NO_RIPEMD	=> 0,
20859191Skris			NO_MDC2		=> 0,
20959191Skris			NO_RSA		=> 0,
21059191Skris			NO_DSA		=> 0,
21159191Skris			NO_DH		=> 0,
21259191Skris			NO_HMAC		=> 0,
21355714Skris		);
21455714Skris		while(<IN>) {
21555714Skris			last if (/BEGIN ERROR CODES/);
21655714Skris			if ($line ne '') {
21755714Skris				$_ = $line . $_;
21855714Skris				$line = '';
21955714Skris			}
22055714Skris
22155714Skris			if (/\\$/) {
22255714Skris				$line = $_;
22355714Skris				next;
22455714Skris			}
22555714Skris
22655714Skris	    		$cpp = 1 if /^#.*ifdef.*cplusplus/;
22755714Skris			if ($cpp) {
22855714Skris				$cpp = 0 if /^#.*endif/;
22955714Skris				next;
23055714Skris	    		}
23155714Skris
23255714Skris			s/\/\*.*?\*\///gs;                   # ignore comments
23355714Skris			s/{[^{}]*}//gs;                      # ignore {} blocks
23455714Skris			if (/^\#\s*ifndef (.*)/) {
23555714Skris				push(@tag,$1);
23655714Skris				$tag{$1}=-1;
23755714Skris				next;
23855714Skris			} elsif (/^\#\s*if !defined\(([^\)]+)\)/) {
23955714Skris				push(@tag,$1);
24055714Skris				$tag{$1}=-1;
24155714Skris				next;
24255714Skris			} elsif (/^\#\s*ifdef (.*)/) {
24355714Skris				push(@tag,$1);
24455714Skris				$tag{$1}=1;
24555714Skris				next;
24655714Skris			} elsif (/^\#\s*if defined(.*)/) {
24755714Skris				push(@tag,$1);
24855714Skris				$tag{$1}=1;
24955714Skris				next;
25055714Skris			} elsif (/^\#\s*endif/) {
25155714Skris				$tag{$tag[$#tag]}=0;
25255714Skris				pop(@tag);
25355714Skris				next;
25455714Skris			} elsif (/^\#\s*else/) {
25555714Skris				my $t=$tag[$#tag];
25655714Skris				$tag{$t}= -$tag{$t};
25755714Skris				next;
25855714Skris			} elsif (/^\#\s*if\s+1/) {
25955714Skris				# Dummy tag
26055714Skris				push(@tag,"TRUE");
26155714Skris				$tag{"TRUE"}=1;
26255714Skris				next;
26359191Skris			} elsif (/^\#\s*if\s+0/) {
26459191Skris				# Dummy tag
26559191Skris				push(@tag,"TRUE");
26659191Skris				$tag{"TRUE"}=-1;
26759191Skris				next;
26855714Skris			} elsif (/^\#/) {
26955714Skris				next;
27055714Skris			}
27155714Skris			if ($safe_stack_def &&
27255714Skris				/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
27355714Skris				$funcs{"sk_${1}_new"} = 1;
27455714Skris				$funcs{"sk_${1}_new_null"} = 1;
27555714Skris				$funcs{"sk_${1}_free"} = 1;
27655714Skris				$funcs{"sk_${1}_num"} = 1;
27755714Skris				$funcs{"sk_${1}_value"} = 1;
27855714Skris				$funcs{"sk_${1}_set"} = 1;
27955714Skris				$funcs{"sk_${1}_zero"} = 1;
28055714Skris				$funcs{"sk_${1}_push"} = 1;
28155714Skris				$funcs{"sk_${1}_unshift"} = 1;
28255714Skris				$funcs{"sk_${1}_find"} = 1;
28355714Skris				$funcs{"sk_${1}_delete"} = 1;
28455714Skris				$funcs{"sk_${1}_delete_ptr"} = 1;
28555714Skris				$funcs{"sk_${1}_insert"} = 1;
28655714Skris				$funcs{"sk_${1}_set_cmp_func"} = 1;
28755714Skris				$funcs{"sk_${1}_dup"} = 1;
28855714Skris				$funcs{"sk_${1}_pop_free"} = 1;
28955714Skris				$funcs{"sk_${1}_shift"} = 1;
29055714Skris				$funcs{"sk_${1}_pop"} = 1;
29155714Skris				$funcs{"sk_${1}_sort"} = 1;
29255714Skris			} elsif ($safe_stack_def &&
29355714Skris				/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
29455714Skris				$funcs{"d2i_ASN1_SET_OF_${1}"} = 1;
29555714Skris				$funcs{"i2d_ASN1_SET_OF_${1}"} = 1;
29655714Skris			} elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
29755714Skris				     /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ) {
29855714Skris				if($W32) {
29955714Skris					$funcs{"PEM_read_${1}"} = 1;
30055714Skris					$funcs{"PEM_write_${1}"} = 1;
30155714Skris				}
30255714Skris				$funcs{"PEM_read_bio_${1}"} = 1;
30355714Skris				$funcs{"PEM_write_bio_${1}"} = 1;
30459191Skris			} elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
30559191Skris				     /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
30659191Skris				if($W32) {
30759191Skris					$funcs{"PEM_write_${1}"} = 1;
30859191Skris				}
30959191Skris				$funcs{"PEM_write_bio_${1}"} = 1;
31059191Skris			} elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
31159191Skris				     /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
31259191Skris				if($W32) {
31359191Skris					$funcs{"PEM_read_${1}"} = 1;
31459191Skris				}
31559191Skris				$funcs{"PEM_read_bio_${1}"} = 1;
31659191Skris			} elsif (
31759191Skris				($tag{'TRUE'} != -1) &&
31855714Skris				($tag{'FreeBSD'} != 1) &&
31955714Skris				($tag{'CONST_STRICT'} != 1) &&
32055714Skris				(($W32 && ($tag{'WIN16'} != 1)) ||
32155714Skris				 (!$W32 && ($tag{'WIN16'} != -1))) &&
32255714Skris				($tag{'PERL5'} != 1) &&
32355714Skris#				($tag{'_WINDLL'} != -1) &&
32455714Skris				((!$W32 && $tag{'_WINDLL'} != -1) ||
32555714Skris				 ($W32 && $tag{'_WINDLL'} != 1)) &&
32655714Skris				((($tag{'NO_FP_API'} != 1) && $W32) ||
32759191Skris				 (($tag{'NO_FP_API'} != -1) && !$W32)) &&
32859191Skris				($tag{'NO_RC2'} == 0  || !$no_rc2) &&
32959191Skris				($tag{'NO_RC4'} == 0  || !$no_rc4) &&
33059191Skris				($tag{'NO_RC5'} == 0  || !$no_rc5) &&
33159191Skris				($tag{'NO_IDEA'} == 0 || !$no_idea) &&
33259191Skris				($tag{'NO_DES'} == 0  || !$no_des) &&
33359191Skris				($tag{'NO_BF'} == 0   || !$no_bf) &&
33459191Skris				($tag{'NO_CAST'} == 0 || !$no_cast) &&
33559191Skris				($tag{'NO_MD2'} == 0  || !$no_md2) &&
33659191Skris				($tag{'NO_MD5'} == 0  || !$no_md5) &&
33759191Skris				($tag{'NO_SHA'} == 0  || !$no_sha) &&
33859191Skris				($tag{'NO_RIPEMD'} == 0 || !$no_ripemd) &&
33959191Skris				($tag{'NO_MDC2'} == 0 || !$no_mdc2) &&
34059191Skris				($tag{'NO_RSA'} == 0  || !$no_rsa) &&
34159191Skris				($tag{'NO_DSA'} == 0  || !$no_dsa) &&
34259191Skris				($tag{'NO_DH'} == 0   || !$no_dh) &&
34359191Skris				($tag{'NO_HMAC'} == 0 || !$no_hmac))
34455714Skris				{
34555714Skris					if (/{|\/\*/) { # }
34655714Skris						$line = $_;
34755714Skris					} else {
34855714Skris						$def .= $_;
34955714Skris					}
35055714Skris				}
35155714Skris			}
35255714Skris		close(IN);
35355714Skris
35455714Skris		foreach (split /;/, $def) {
35555714Skris			s/^[\n\s]*//g;
35655714Skris			s/[\n\s]*$//g;
35755714Skris			next if(/typedef\W/);
35855714Skris			next if(/EVP_bf/ and $no_bf);
35955714Skris			next if(/EVP_cast/ and $no_cast);
36055714Skris			next if(/EVP_des/ and $no_des);
36155714Skris			next if(/EVP_dss/ and $no_dsa);
36255714Skris			next if(/EVP_idea/ and $no_idea);
36355714Skris			next if(/EVP_md2/ and $no_md2);
36455714Skris			next if(/EVP_md5/ and $no_md5);
36555714Skris			next if(/EVP_rc2/ and $no_rc2);
36655714Skris			next if(/EVP_rc4/ and $no_rc4);
36755714Skris			next if(/EVP_rc5/ and $no_rc5);
36855714Skris			next if(/EVP_ripemd/ and $no_ripemd);
36955714Skris			next if(/EVP_sha/ and $no_sha);
37055714Skris			if (/\(\*(\w*)\([^\)]+/) {
37155714Skris				$funcs{$1} = 1;
37255714Skris			} elsif (/\w+\W+(\w+)\W*\(\s*\)$/s) {
37355714Skris				# K&R C
37455714Skris				next;
37555714Skris			} elsif (/\w+\W+\w+\W*\(.*\)$/s) {
37655714Skris				while (not /\(\)$/s) {
37755714Skris					s/[^\(\)]*\)$/\)/s;
37855714Skris					s/\([^\(\)]*\)\)$/\)/s;
37955714Skris				}
38055714Skris				s/\(void\)//;
38155714Skris				/(\w+)\W*\(\)/s;
38255714Skris				$funcs{$1} = 1;
38355714Skris			} elsif (/\(/ and not (/=/)) {
38455714Skris				print STDERR "File $file: cannot parse: $_;\n";
38555714Skris			}
38655714Skris		}
38755714Skris	}
38855714Skris
38955714Skris	# Prune the returned functions
39055714Skris
39155714Skris        delete $funcs{"SSL_add_dir_cert_subjects_to_stack"};
39255714Skris        delete $funcs{"RSA_PKCS1_RSAref"} unless $rsaref;
39359191Skris        delete $funcs{"bn_dump1"};
39455714Skris
39555714Skris	if($W32) {
39655714Skris		delete $funcs{"BIO_s_file_internal"};
39755714Skris		delete $funcs{"BIO_new_file_internal"};
39855714Skris		delete $funcs{"BIO_new_fp_internal"};
39955714Skris	} else {
40055714Skris		if(exists $funcs{"ERR_load_CRYPTO_strings"}) {
40155714Skris			delete $funcs{"ERR_load_CRYPTO_strings"};
40255714Skris			$funcs{"ERR_load_CRYPTOlib_strings"} = 1;
40355714Skris		}
40455714Skris		delete $funcs{"BIO_s_file"};
40555714Skris		delete $funcs{"BIO_new_file"};
40655714Skris		delete $funcs{"BIO_new_fp"};
40755714Skris	}
40855714Skris	if (!$NT) {
40955714Skris		delete $funcs{"BIO_s_log"};
41055714Skris	}
41155714Skris
41255714Skris	push @ret, keys %funcs;
41355714Skris
41455714Skris	return(@ret);
41555714Skris}
41655714Skris
41759191Skrissub print_test_file
41859191Skris{
41959191Skris	(*OUT,my $name,*nums,my @functions)=@_;
42059191Skris	my $n = 1; my @e; my @r;
42159191Skris	my $func;
42259191Skris
42359191Skris	(@e)=grep(/^SSLeay/,@functions);
42459191Skris	(@r)=grep(!/^SSLeay/,@functions);
42559191Skris	@functions=((sort @e),(sort @r));
42659191Skris
42759191Skris	foreach $func (@functions) {
42859191Skris		if (!defined($nums{$func})) {
42959191Skris			printf STDERR "$func does not have a number assigned\n"
43059191Skris					if(!$do_update);
43159191Skris		} else {
43259191Skris			$n=$nums{$func};
43359191Skris			print OUT "\t$func();\n";
43459191Skris		}
43559191Skris	}
43659191Skris}
43759191Skris
43855714Skrissub print_def_file
43955714Skris{
44059191Skris	(*OUT,my $name,*nums,my @functions)=@_;
44159191Skris	my $n = 1; my @e; my @r;
44255714Skris
44355714Skris	if ($W32)
44455714Skris		{ $name.="32"; }
44555714Skris	else
44655714Skris		{ $name.="16"; }
44755714Skris
44855714Skris	print OUT <<"EOF";
44955714Skris;
45055714Skris; Definition file for the DLL version of the $name library from OpenSSL
45155714Skris;
45255714Skris
45355714SkrisLIBRARY         $name
45455714Skris
45555714SkrisDESCRIPTION     'OpenSSL $name - http://www.openssl.org/'
45655714Skris
45755714SkrisEOF
45855714Skris
45955714Skris	if (!$W32) {
46055714Skris		print <<"EOF";
46155714SkrisCODE            PRELOAD MOVEABLE
46255714SkrisDATA            PRELOAD MOVEABLE SINGLE
46355714Skris
46455714SkrisEXETYPE		WINDOWS
46555714Skris
46655714SkrisHEAPSIZE	4096
46755714SkrisSTACKSIZE	8192
46855714Skris
46955714SkrisEOF
47055714Skris	}
47155714Skris
47255714Skris	print "EXPORTS\n";
47355714Skris
47455714Skris
47555714Skris	(@e)=grep(/^SSLeay/,@functions);
47655714Skris	(@r)=grep(!/^SSLeay/,@functions);
47755714Skris	@functions=((sort @e),(sort @r));
47855714Skris
47955714Skris	foreach $func (@functions) {
48055714Skris		if (!defined($nums{$func})) {
48155714Skris			printf STDERR "$func does not have a number assigned\n"
48255714Skris					if(!$do_update);
48355714Skris		} else {
48455714Skris			$n=$nums{$func};
48555714Skris			printf OUT "    %s%-40s@%d\n",($W32)?"":"_",$func,$n;
48655714Skris		}
48755714Skris	}
48855714Skris	printf OUT "\n";
48955714Skris}
49055714Skris
49155714Skrissub load_numbers
49255714Skris{
49355714Skris	my($name)=@_;
49455714Skris	my(@a,%ret);
49555714Skris
49655714Skris	$max_num = 0;
49755714Skris
49855714Skris	open(IN,"<$name") || die "unable to open $name:$!\n";
49955714Skris	while (<IN>) {
50055714Skris		chop;
50155714Skris		s/#.*$//;
50255714Skris		next if /^\s*$/;
50355714Skris		@a=split;
50455714Skris		$ret{$a[0]}=$a[1];
50555714Skris		$max_num = $a[1] if $a[1] > $max_num;
50655714Skris	}
50755714Skris	close(IN);
50855714Skris	return(%ret);
50955714Skris}
51055714Skris
51155714Skrissub update_numbers
51255714Skris{
51355714Skris	(*OUT,$name,*nums,my $start_num, my @functions)=@_;
51455714Skris	my $new_funcs = 0;
51555714Skris	print STDERR "Updating $name\n";
51655714Skris	foreach $func (@functions) {
51755714Skris		if (!exists $nums{$func}) {
51855714Skris			$new_funcs++;
51955714Skris			printf OUT "%s%-40s%d\n","",$func, ++$start_num;
52055714Skris		}
52155714Skris	}
52255714Skris	if($new_funcs) {
52355714Skris		print STDERR "$new_funcs New Functions added\n";
52455714Skris	} else {
52555714Skris		print STDERR "No New Functions Added\n";
52655714Skris	}
52755714Skris}
528