mkdef.pl revision 238405
19313Ssos#!/usr/local/bin/perl -w
2230132Suqs#
39313Ssos# generate a .def file
49313Ssos#
59313Ssos# It does this by parsing the header files and looking for the
69313Ssos# prototyped functions: it then prunes the output.
79313Ssos#
89313Ssos# Intermediary files are created, call libeay.num and ssleay.num,...
9111798Sdes# Previously, they had the following format:
109313Ssos#
119313Ssos#	routine-name	nnnn
129313Ssos#
139313Ssos# But that isn't enough for a number of reasons, the first on being that
149313Ssos# this format is (needlessly) very Win32-centric, and even then...
1597748Sschweikh# One of the biggest problems is that there's no information about what
169313Ssos# routines should actually be used, which varies with what crypto algorithms
179313Ssos# are disabled.  Also, some operating systems (for example VMS with VAX C)
189313Ssos# need to keep track of the global variables as well as the functions.
199313Ssos#
209313Ssos# So, a remake of this script is done so as to include information on the
219313Ssos# kind of symbol it is (function or variable) and what algorithms they're
229313Ssos# part of.  This will allow easy translating to .def files or the corresponding
239313Ssos# file in other operating systems (a .opt file for VMS, possibly with a .mar
249313Ssos# file).
259313Ssos#
269313Ssos# The format now becomes:
279313Ssos#
289313Ssos#	routine-name	nnnn	info
29116173Sobrien#
30116173Sobrien# and the "info" part is actually a colon-separated string of fields with
31116173Sobrien# the following meaning:
32156874Sru#
3331784Seivind#	existence:platform:kind:algorithms
349313Ssos#
359313Ssos# - "existence" can be "EXIST" or "NOEXIST" depending on if the symbol is
36263233Srwatson#   found somewhere in the source,
3776166Smarkm# - "platforms" is empty if it exists on all platforms, otherwise it contains
3876166Smarkm#   comma-separated list of the platform, just as they are if the symbol exists
399313Ssos#   for those platforms, or prepended with a "!" if not.  This helps resolve
409313Ssos#   symbol name variants for platforms where the names are too long for the
419313Ssos#   compiler or linker, or if the systems is case insensitive and there is a
4231561Sbde#   clash, or the symbol is implemented differently (see
439313Ssos#   EXPORT_VAR_AS_FUNCTION).  This script assumes renaming of symbols is found
4472538Sjlemon#   in the file crypto/symhacks.h.
4576166Smarkm#   The semantics for the platforms is that every item is checked against the
46168014Sjulian#   environment.  For the negative items ("!FOO"), if any of them is false
4776166Smarkm#   (i.e. "FOO" is true) in the environment, the corresponding symbol can't be
48162201Snetchild#   used.  For the positive itms, if all of them are false in the environment,
49166085Skib#   the corresponding symbol can't be used.  Any combination of positive and
50102814Siedowse#   negative items are possible, and of course leave room for some redundancy.
5176166Smarkm# - "kind" is "FUNCTION" or "VARIABLE".  The meaning of that is obvious.
5214331Speter# - "algorithms" is a comma-separated list of algorithm names.  This helps
53162585Snetchild#   exclude symbols that are part of an algorithm that some user wants to
5476166Smarkm#   exclude.
5512458Sbde#
56163606Srwatson
57163606Srwatsonmy $debug=0;
58140214Sobrien
59140214Sobrienmy $crypto_num= "util/libeay.num";
60140214Sobrienmy $ssl_num=    "util/ssleay.num";
61140214Sobrienmy $libname;
6264905Smarcel
6368583Smarcelmy $do_update = 0;
64133816Stjrmy $do_rewrite = 1;
65246085Sjhbmy $do_crypto = 0;
6664905Smarcelmy $do_ssl = 0;
67177997Skibmy $do_ctest = 0;
689313Ssosmy $do_ctestall = 0;
699313Ssosmy $do_checkexist = 0;
7083366Sjulian
719313Ssosmy $VMSVAX=0;
72300411Sdchaginmy $VMSNonVAX=0;
73300411Sdchaginmy $VMS=0;
749313Ssosmy $W32=0;
75300411Sdchaginmy $W16=0;
769313Ssosmy $NT=0;
7772543Sjlemonmy $OS2=0;
78102814Siedowse# Set this to make typesafe STACK definitions appear in DEF
799313Ssosmy $safe_stack_def = 0;
80300411Sdchagin
81300411Sdchaginmy @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
82300411Sdchagin			"EXPORT_VAR_AS_FUNCTION", "ZLIB", "OPENSSL_FIPS" );
83300411Sdchaginmy @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
849313Ssosmy @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
859313Ssos			 "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
86168014Sjulian			 "SHA256", "SHA512", "RIPEMD",
87168014Sjulian			 "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M",
88177997Skib			 "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
899313Ssos			 # EC_NISTP_64_GCC_128
90300411Sdchagin			 "EC_NISTP_64_GCC_128",
91300411Sdchagin			 # Envelope "algorithms"
92300411Sdchagin			 "EVP", "X509", "ASN1_TYPEDEFS",
93300411Sdchagin			 # Helper "algorithms"
94300411Sdchagin			 "BIO", "COMP", "BUFFER", "LHASH", "STACK", "ERR",
9514331Speter			 "LOCKING",
96300411Sdchagin			 # External "algorithms"
97300411Sdchagin			 "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
98300411Sdchagin			 # Engines
99300411Sdchagin			 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
100300411Sdchagin			 # RFC3779
101300411Sdchagin			 "RFC3779",
102300411Sdchagin			 # TLS
103300411Sdchagin			 "TLSEXT", "PSK", "SRP", "HEARTBEATS",
104300411Sdchagin			 # CMS
105300411Sdchagin			 "CMS",
106300411Sdchagin			 # CryptoAPI Engine
107300411Sdchagin			 "CAPIENG",
108300411Sdchagin			 # SSL v2
109300411Sdchagin			 "SSL2",
110300411Sdchagin			 # JPAKE
111300411Sdchagin			 "JPAKE",
112300411Sdchagin			 # NEXTPROTONEG
113300411Sdchagin			 "NEXTPROTONEG",
114300411Sdchagin			 # Deprecated functions
115300411Sdchagin			 "DEPRECATED",
116300411Sdchagin			 # Hide SSL internals
117300411Sdchagin			 "SSL_INTERN",
118300411Sdchagin			 # SCTP
119300411Sdchagin			 "SCTP");
120300411Sdchagin
121300411Sdchaginmy $options="";
122300411Sdchaginopen(IN,"<Makefile") || die "unable to open Makefile!\n";
123300411Sdchaginwhile(<IN>) {
124300411Sdchagin    $options=$1 if (/^OPTIONS=(.*)$/);
125300411Sdchagin}
126300411Sdchaginclose(IN);
127300411Sdchagin
128300411Sdchagin# The following ciphers may be excluded (by Configure). This means functions
129300411Sdchagin# defined with ifndef(NO_XXX) are not included in the .def file, and everything
130300411Sdchagin# in directory xxx is ignored.
131300411Sdchaginmy $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
1329313Ssosmy $no_cast; my $no_whirlpool; my $no_camellia; my $no_seed;
133300411Sdchaginmy $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
134300411Sdchaginmy $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
135300411Sdchaginmy $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
136300411Sdchaginmy $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
137300411Sdchaginmy $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
138178036Srdivackymy $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc;
139300411Sdchaginmy $no_nextprotoneg; my $no_sctp;
140300411Sdchagin
141300411Sdchaginmy $fips;
142300411Sdchagin
143300411Sdchaginmy $zlib;
144300411Sdchagin
145300411Sdchagin
146300411Sdchaginforeach (@ARGV, split(/ /, $options))
147300411Sdchagin	{
148300411Sdchagin	$debug=1 if $_ eq "debug";
149300411Sdchagin	$W32=1 if $_ eq "32";
150300411Sdchagin	$W16=1 if $_ eq "16";
151300411Sdchagin	if($_ eq "NT") {
152300411Sdchagin		$W32 = 1;
153300411Sdchagin		$NT = 1;
154300411Sdchagin	}
155300411Sdchagin	if ($_ eq "VMS-VAX") {
156300411Sdchagin		$VMS=1;
157300411Sdchagin		$VMSVAX=1;
158300411Sdchagin	}
159300411Sdchagin	if ($_ eq "VMS-NonVAX") {
160300411Sdchagin		$VMS=1;
161300411Sdchagin		$VMSNonVAX=1;
162300411Sdchagin	}
163300411Sdchagin	$VMS=1 if $_ eq "VMS";
164281726Strasz	$OS2=1 if $_ eq "OS2";
165281726Strasz	$fips=1 if /^fips/;
16614331Speter	if ($_ eq "zlib" || $_ eq "enable-zlib" || $_ eq "zlib-dynamic"
167300411Sdchagin			 || $_ eq "enable-zlib-dynamic") {
168300411Sdchagin		$zlib = 1;
16914331Speter	}
170300411Sdchagin
171300411Sdchagin	$do_ssl=1 if $_ eq "ssleay";
1729313Ssos	if ($_ eq "ssl") {
1739313Ssos		$do_ssl=1;
1749313Ssos		$libname=$_
175168014Sjulian	}
176168014Sjulian	$do_crypto=1 if $_ eq "libeay";
177177997Skib	if ($_ eq "crypto") {
178177997Skib		$do_crypto=1;
179168014Sjulian		$libname=$_;
180177997Skib	}
181177997Skib	$no_static_engine=1 if $_ eq "no-static-engine";
182177997Skib	$no_static_engine=0 if $_ eq "enable-static-engine";
183177997Skib	$do_update=1 if $_ eq "update";
184177997Skib	$do_rewrite=1 if $_ eq "rewrite";
185168014Sjulian	$do_ctest=1 if $_ eq "ctest";
186168014Sjulian	$do_ctestall=1 if $_ eq "ctestall";
187168014Sjulian	$do_checkexist=1 if $_ eq "exist";
188177997Skib	#$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK";
189168014Sjulian
190177997Skib	if    (/^no-rc2$/)      { $no_rc2=1; }
191168014Sjulian	elsif (/^no-rc4$/)      { $no_rc4=1; }
192168014Sjulian	elsif (/^no-rc5$/)      { $no_rc5=1; }
193168014Sjulian	elsif (/^no-idea$/)     { $no_idea=1; }
194168014Sjulian	elsif (/^no-des$/)      { $no_des=1; $no_mdc2=1; }
195168014Sjulian	elsif (/^no-bf$/)       { $no_bf=1; }
196300411Sdchagin	elsif (/^no-cast$/)     { $no_cast=1; }
197168014Sjulian	elsif (/^no-whirlpool$/)     { $no_whirlpool=1; }
198300411Sdchagin	elsif (/^no-md2$/)      { $no_md2=1; }
199300411Sdchagin	elsif (/^no-md4$/)      { $no_md4=1; }
200300411Sdchagin	elsif (/^no-md5$/)      { $no_md5=1; }
201300411Sdchagin	elsif (/^no-sha$/)      { $no_sha=1; }
202168014Sjulian	elsif (/^no-ripemd$/)   { $no_ripemd=1; }
203168014Sjulian	elsif (/^no-mdc2$/)     { $no_mdc2=1; }
204168014Sjulian	elsif (/^no-rsa$/)      { $no_rsa=1; }
205168014Sjulian	elsif (/^no-dsa$/)      { $no_dsa=1; }
206168014Sjulian	elsif (/^no-dh$/)       { $no_dh=1; }
207178036Srdivacky	elsif (/^no-ec$/)       { $no_ec=1; }
208168014Sjulian	elsif (/^no-ecdsa$/)	{ $no_ecdsa=1; }
209168014Sjulian	elsif (/^no-ecdh$/) 	{ $no_ecdh=1; }
210168014Sjulian	elsif (/^no-hmac$/)	{ $no_hmac=1; }
21183366Sjulian	elsif (/^no-aes$/)	{ $no_aes=1; }
2129313Ssos	elsif (/^no-camellia$/)	{ $no_camellia=1; }
213300411Sdchagin	elsif (/^no-seed$/)     { $no_seed=1; }
214300411Sdchagin	elsif (/^no-evp$/)	{ $no_evp=1; }
215300411Sdchagin	elsif (/^no-lhash$/)	{ $no_lhash=1; }
216300411Sdchagin	elsif (/^no-stack$/)	{ $no_stack=1; }
217300411Sdchagin	elsif (/^no-err$/)	{ $no_err=1; }
218300411Sdchagin	elsif (/^no-buffer$/)	{ $no_buffer=1; }
219300411Sdchagin	elsif (/^no-bio$/)	{ $no_bio=1; }
2209313Ssos	#elsif (/^no-locking$/)	{ $no_locking=1; }
2219313Ssos	elsif (/^no-comp$/)	{ $no_comp=1; }
22272543Sjlemon	elsif (/^no-dso$/)	{ $no_dso=1; }
22372543Sjlemon	elsif (/^no-krb5$/)	{ $no_krb5=1; }
22483221Smarcel	elsif (/^no-engine$/)	{ $no_engine=1; }
2259313Ssos	elsif (/^no-hw$/)	{ $no_hw=1; }
226300411Sdchagin	elsif (/^no-gmp$/)	{ $no_gmp=1; }
227300411Sdchagin	elsif (/^no-rfc3779$/)	{ $no_rfc3779=1; }
228300411Sdchagin	elsif (/^no-tlsext$/)	{ $no_tlsext=1; }
229300411Sdchagin	elsif (/^no-cms$/)	{ $no_cms=1; }
230300411Sdchagin	elsif (/^no-ec2m$/)	{ $no_ec2m=1; }
2319313Ssos	elsif (/^no-ec_nistp_64_gcc_128$/)	{ $no_nistp_gcc=1; }
2329313Ssos	elsif (/^no-nextprotoneg$/)	{ $no_nextprotoneg=1; }
233283415Sdchagin	elsif (/^no-ssl2$/)	{ $no_ssl2=1; }
23414331Speter	elsif (/^no-capieng$/)	{ $no_capieng=1; }
23583366Sjulian	elsif (/^no-jpake$/)	{ $no_jpake=1; }
23614331Speter	elsif (/^no-srp$/)	{ $no_srp=1; }
23714331Speter	elsif (/^no-sctp$/)	{ $no_sctp=1; }
23814331Speter	}
23914331Speter
24014331Speter
24114331Speterif (!$libname) {
24272543Sjlemon	if ($do_ssl) {
24372543Sjlemon		$libname="SSLEAY";
24472543Sjlemon	}
24514331Speter	if ($do_crypto) {
24614331Speter		$libname="LIBEAY";
24714331Speter	}
24814331Speter}
24914331Speter
25014331Speter# If no platform is given, assume WIN32
25114331Speterif ($W32 + $W16 + $VMS + $OS2 == 0) {
252225617Skmacy	$W32 = 1;
253300411Sdchagin}
25414331Speter
255111797Sdes# Add extra knowledge
256300411Sdchaginif ($W16) {
25714331Speter	$no_fp_api=1;
25883366Sjulian}
259300411Sdchagin
26014331Speterif (!$do_ssl && !$do_crypto)
26114331Speter	{
2629313Ssos	print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT | OS2 ]\n";
26383366Sjulian	exit(1);
2649313Ssos	}
26514331Speter
26614331Speter%ssl_list=&load_numbers($ssl_num);
26714331Speter$max_ssl = $max_num;
26814331Speter%crypto_list=&load_numbers($crypto_num);
26914331Speter$max_crypto = $max_num;
270300411Sdchagin
27114331Spetermy $ssl="ssl/ssl.h";
272283415Sdchagin$ssl.=" ssl/kssl.h";
27314331Speter$ssl.=" ssl/tls1.h";
27483221Smarcel$ssl.=" ssl/srtp.h";
27583221Smarcel
27683221Smarcelmy $crypto ="crypto/crypto.h";
27783221Smarcel$crypto.=" crypto/cryptlib.h";
27883221Smarcel$crypto.=" crypto/o_dir.h";
27983221Smarcel$crypto.=" crypto/o_str.h";
28083221Smarcel$crypto.=" crypto/o_time.h";
28183221Smarcel$crypto.=" crypto/des/des.h crypto/des/des_old.h" ; # unless $no_des;
28283221Smarcel$crypto.=" crypto/idea/idea.h" ; # unless $no_idea;
28383221Smarcel$crypto.=" crypto/rc4/rc4.h" ; # unless $no_rc4;
284179651Srdivacky$crypto.=" crypto/rc5/rc5.h" ; # unless $no_rc5;
28583221Smarcel$crypto.=" crypto/rc2/rc2.h" ; # unless $no_rc2;
28683221Smarcel$crypto.=" crypto/bf/blowfish.h" ; # unless $no_bf;
28783221Smarcel$crypto.=" crypto/cast/cast.h" ; # unless $no_cast;
28883221Smarcel$crypto.=" crypto/whrlpool/whrlpool.h" ;
28983221Smarcel$crypto.=" crypto/md2/md2.h" ; # unless $no_md2;
29083221Smarcel$crypto.=" crypto/md4/md4.h" ; # unless $no_md4;
29183221Smarcel$crypto.=" crypto/md5/md5.h" ; # unless $no_md5;
29283221Smarcel$crypto.=" crypto/mdc2/mdc2.h" ; # unless $no_mdc2;
29383221Smarcel$crypto.=" crypto/sha/sha.h" ; # unless $no_sha;
29483221Smarcel$crypto.=" crypto/ripemd/ripemd.h" ; # unless $no_ripemd;
29583221Smarcel$crypto.=" crypto/aes/aes.h" ; # unless $no_aes;
29683221Smarcel$crypto.=" crypto/camellia/camellia.h" ; # unless $no_camellia;
29783221Smarcel$crypto.=" crypto/seed/seed.h"; # unless $no_seed;
298182892Srdivacky
299182892Srdivacky$crypto.=" crypto/bn/bn.h";
300182892Srdivacky$crypto.=" crypto/rsa/rsa.h" ; # unless $no_rsa;
301182892Srdivacky$crypto.=" crypto/dsa/dsa.h" ; # unless $no_dsa;
302182892Srdivacky$crypto.=" crypto/dh/dh.h" ; # unless $no_dh;
303298482Spfg$crypto.=" crypto/ec/ec.h" ; # unless $no_ec;
30483221Smarcel$crypto.=" crypto/ecdsa/ecdsa.h" ; # unless $no_ecdsa;
305182892Srdivacky$crypto.=" crypto/ecdh/ecdh.h" ; # unless $no_ecdh;
306298482Spfg$crypto.=" crypto/hmac/hmac.h" ; # unless $no_hmac;
307182892Srdivacky$crypto.=" crypto/cmac/cmac.h" ; # unless $no_hmac;
308182892Srdivacky
309182892Srdivacky$crypto.=" crypto/engine/engine.h"; # unless $no_engine;
310182892Srdivacky$crypto.=" crypto/stack/stack.h" ; # unless $no_stack;
31183221Smarcel$crypto.=" crypto/buffer/buffer.h" ; # unless $no_buffer;
31283221Smarcel$crypto.=" crypto/bio/bio.h" ; # unless $no_bio;
31383221Smarcel$crypto.=" crypto/dso/dso.h" ; # unless $no_dso;
31483366Sjulian$crypto.=" crypto/lhash/lhash.h" ; # unless $no_lhash;
31583221Smarcel$crypto.=" crypto/conf/conf.h";
31614331Speter$crypto.=" crypto/txt_db/txt_db.h";
317111798Sdes
31883221Smarcel$crypto.=" crypto/evp/evp.h" ; # unless $no_evp;
31983221Smarcel$crypto.=" crypto/objects/objects.h";
32083221Smarcel$crypto.=" crypto/pem/pem.h";
32183221Smarcel#$crypto.=" crypto/meth/meth.h";
32283221Smarcel$crypto.=" crypto/asn1/asn1.h";
323182892Srdivacky$crypto.=" crypto/asn1/asn1t.h";
324255219Spjd$crypto.=" crypto/asn1/asn1_mac.h";
32583221Smarcel$crypto.=" crypto/err/err.h" ; # unless $no_err;
32683221Smarcel$crypto.=" crypto/pkcs7/pkcs7.h";
32783221Smarcel$crypto.=" crypto/pkcs12/pkcs12.h";
32883221Smarcel$crypto.=" crypto/x509/x509.h";
329182892Srdivacky$crypto.=" crypto/x509/x509_vfy.h";
330182892Srdivacky$crypto.=" crypto/x509v3/x509v3.h";
33183221Smarcel$crypto.=" crypto/ts/ts.h";
33283221Smarcel$crypto.=" crypto/rand/rand.h";
333241896Skib$crypto.=" crypto/comp/comp.h" ; # unless $no_comp;
3349313Ssos$crypto.=" crypto/ocsp/ocsp.h";
335160276Sjhb$crypto.=" crypto/ui/ui.h crypto/ui/ui_compat.h";
336160276Sjhb$crypto.=" crypto/krb5/krb5_asn.h";
337160276Sjhb#$crypto.=" crypto/store/store.h";
338160276Sjhb$crypto.=" crypto/pqueue/pqueue.h";
339160276Sjhb$crypto.=" crypto/cms/cms.h";
340188572Snetchild$crypto.=" crypto/jpake/jpake.h";
341160276Sjhb$crypto.=" crypto/modes/modes.h";
342160276Sjhb$crypto.=" crypto/srp/srp.h";
343160276Sjhb
344160276Sjhbmy $symhacks="crypto/symhacks.h";
345284446Smjg
346255219Spjdmy @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks);
34783221Smarcelmy @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks);
3489313Ssos
34989306Salfredif ($do_update) {
35089306Salfred
35183221Smarcelif ($do_ssl == 1) {
35289306Salfred
3539313Ssos	&maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols);
354238029Skib	if ($do_rewrite == 1) {
355116678Sphk		open(OUT, ">$ssl_num");
35689306Salfred		&rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols);
357238029Skib	} else {
35889306Salfred		open(OUT, ">>$ssl_num");
35983221Smarcel	}
36089306Salfred	&update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols);
3619313Ssos	close OUT;
3629313Ssos}
36383221Smarcel
36483221Smarcelif($do_crypto == 1) {
365283427Sdchagin
366283427Sdchagin	&maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols);
367188588Sjhb	if ($do_rewrite == 1) {
36883221Smarcel		open(OUT, ">$crypto_num");
36983221Smarcel		&rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols);
37083221Smarcel	} else {
37183221Smarcel		open(OUT, ">>$crypto_num");
37283221Smarcel	}
37383221Smarcel	&update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols);
37483221Smarcel	close OUT;
37583366Sjulian}
37683221Smarcel
37783221Smarcel} elsif ($do_checkexist) {
3789313Ssos	&check_existing(*ssl_list, @ssl_symbols)
379101189Srwatson		if $do_ssl == 1;
380101189Srwatson	&check_existing(*crypto_list, @crypto_symbols)
381101189Srwatson		if $do_crypto == 1;
382101189Srwatson} elsif ($do_ctest || $do_ctestall) {
383172930Srwatson
384101189Srwatson	print <<"EOF";
385101189Srwatson
38683221Smarcel/* Test file to check all DEF file symbols are present by trying
38783221Smarcel * to link to all of them. This is *not* intended to be run!
38883221Smarcel */
3899313Ssos
39083221Smarcelint main()
39183221Smarcel{
39283221SmarcelEOF
39383221Smarcel	&print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols)
39483221Smarcel		if $do_ssl == 1;
3959313Ssos
39683221Smarcel	&print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols)
39724654Sdfr		if $do_crypto == 1;
39883221Smarcel
39983221Smarcel	print "}\n";
40083221Smarcel
40183221Smarcel} else {
40283221Smarcel
40383221Smarcel	&print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
40483221Smarcel		if $do_ssl == 1;
40583221Smarcel
40683221Smarcel	&print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
40783221Smarcel		if $do_crypto == 1;
40883221Smarcel
40983221Smarcel}
41083221Smarcel
41183221Smarcel
41283221Smarcelsub do_defs
41324654Sdfr{
41424654Sdfr	my($name,$files,$symhacksfile)=@_;
41583221Smarcel	my $file;
41683221Smarcel	my @ret;
41783221Smarcel	my %syms;
41883221Smarcel	my %platform;		# For anything undefined, we assume ""
41983221Smarcel	my %kind;		# For anything undefined, we assume "FUNCTION"
42083221Smarcel	my %algorithm;		# For anything undefined, we assume ""
42183221Smarcel	my %variant;
42283221Smarcel	my %variant_cnt;	# To be able to allocate "name{n}" if "name"
42383221Smarcel				# is the same name as the original.
42483221Smarcel	my $cpp;
42583221Smarcel	my %unknown_algorithms = ();
42683221Smarcel
42783221Smarcel	foreach $file (split(/\s+/,$symhacksfile." ".$files))
42883221Smarcel		{
42983221Smarcel		print STDERR "DEBUG: starting on $file:\n" if $debug;
43083221Smarcel		open(IN,"<$file") || die "unable to open $file:$!\n";
43183221Smarcel		my $line = "", my $def= "";
43283221Smarcel		my %tag = (
43383221Smarcel			(map { $_ => 0 } @known_platforms),
43483221Smarcel			(map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
43583221Smarcel			(map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
43683221Smarcel			NOPROTO		=> 0,
43783221Smarcel			PERL5		=> 0,
438182892Srdivacky			_WINDLL		=> 0,
439182892Srdivacky			CONST_STRICT	=> 0,
44083221Smarcel			TRUE		=> 1,
44183221Smarcel		);
44283221Smarcel		my $symhacking = $file eq $symhacksfile;
44383221Smarcel		my @current_platforms = ();
44483221Smarcel		my @current_algorithms = ();
44583221Smarcel
44683221Smarcel		# params: symbol, alias, platforms, kind
44783221Smarcel		# The reason to put this subroutine in a variable is that
448182892Srdivacky		# it will otherwise create it's own, unshared, version of
449182892Srdivacky		# %tag and %variant...
450182892Srdivacky		my $make_variant = sub
451182892Srdivacky		{
452182892Srdivacky			my ($s, $a, $p, $k) = @_;
453182892Srdivacky			my ($a1, $a2);
454182892Srdivacky
45583221Smarcel			print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
456182892Srdivacky			if (defined($p))
457182892Srdivacky			{
458182892Srdivacky				$a1 = join(",",$p,
459182892Srdivacky					   grep(!/^$/,
460182892Srdivacky						map { $tag{$_} == 1 ? $_ : "" }
461182892Srdivacky						@known_platforms));
462182892Srdivacky			}
463182892Srdivacky			else
464182892Srdivacky			{
465182892Srdivacky				$a1 = join(",",
466182892Srdivacky					   grep(!/^$/,
467182892Srdivacky						map { $tag{$_} == 1 ? $_ : "" }
468182892Srdivacky						@known_platforms));
469182892Srdivacky			}
470182892Srdivacky			$a2 = join(",",
471182892Srdivacky				   grep(!/^$/,
472182892Srdivacky					map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
473182892Srdivacky					@known_ossl_platforms));
474182892Srdivacky			print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
475182892Srdivacky			if ($a1 eq "") { $a1 = $a2; }
476182892Srdivacky			elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
477182892Srdivacky			if ($a eq $s)
478182892Srdivacky			{
479182892Srdivacky				if (!defined($variant_cnt{$s}))
480182892Srdivacky				{
481182892Srdivacky					$variant_cnt{$s} = 0;
482182892Srdivacky				}
48383221Smarcel				$variant_cnt{$s}++;
48483221Smarcel				$a .= "{$variant_cnt{$s}}";
48583221Smarcel			}
48683221Smarcel			my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
48783221Smarcel			my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
48883221Smarcel			if (!grep(/^$togrep$/,
48983221Smarcel				  split(/;/, defined($variant{$s})?$variant{$s}:""))) {
49083221Smarcel				if (defined($variant{$s})) { $variant{$s} .= ";"; }
49183221Smarcel				$variant{$s} .= $toadd;
49283221Smarcel			}
49383221Smarcel			print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
49483221Smarcel		};
49583221Smarcel
49683221Smarcel		print STDERR "DEBUG: parsing ----------\n" if $debug;
49783221Smarcel		while(<IN>) {
49810355Sswallace			if (/\/\* Error codes for the \w+ functions\. \*\//)
4999313Ssos				{
500217578Skib				undef @tag;
501217578Skib				last;
502217578Skib				}
503217578Skib			if ($line ne '') {
5049313Ssos				$_ = $line . $_;
50583221Smarcel				$line = '';
50683221Smarcel			}
50710355Sswallace
5089313Ssos			if (/\\$/) {
50983366Sjulian				chomp; # remove eol
51083221Smarcel				chop; # remove ending backslash
5119313Ssos				$line = $_;
512247764Seadler				next;
51383221Smarcel			}
514175294Sattilio
515238029Skib			if(/\/\*/) {
51689306Salfred				if (not /\*\//) {	# multiline comment...
517283427Sdchagin					$line = $_;	# ... just accumulate
518283427Sdchagin					next;
51983221Smarcel				} else {
5209313Ssos					s/\/\*.*?\*\///gs;# wipe it
52114331Speter				}
52283221Smarcel			}
52383366Sjulian
52483221Smarcel			if ($cpp) {
52583221Smarcel				$cpp++ if /^#\s*if/;
52683221Smarcel				$cpp-- if /^#\s*endif/;
52783221Smarcel				next;
52883221Smarcel	    		}
52983221Smarcel			$cpp = 1 if /^#.*ifdef.*cplusplus/;
53083221Smarcel
53183366Sjulian			s/{[^{}]*}//gs;                      # ignore {} blocks
53283221Smarcel			print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
53383221Smarcel			print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
53483221Smarcel			if (/^\#\s*ifndef\s+(.*)/) {
53583366Sjulian				push(@tag,"-");
53683221Smarcel				push(@tag,$1);
53783221Smarcel				$tag{$1}=-1;
53883221Smarcel				print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
53983221Smarcel			} elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
54083221Smarcel				push(@tag,"-");
54183221Smarcel				if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
54283221Smarcel					my $tmp_1 = $1;
54383366Sjulian					my $tmp_;
54483221Smarcel					foreach $tmp_ (split '\&\&',$tmp_1) {
54583221Smarcel						$tmp_ =~ /!defined\(([^\)]+)\)/;
54614331Speter						print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
54714331Speter						push(@tag,$1);
54814331Speter						$tag{$1}=-1;
54914331Speter					}
55014331Speter				} else {
55183366Sjulian					print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
55214331Speter					print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
553102814Siedowse					push(@tag,$1);
554102814Siedowse					$tag{$1}=-1;
55514331Speter				}
556162585Snetchild			} elsif (/^\#\s*ifdef\s+(\S*)/) {
557227691Sed				push(@tag,"-");
558162585Snetchild				push(@tag,$1);
559162585Snetchild				$tag{$1}=1;
560102814Siedowse				print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
56114331Speter			} elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
56214331Speter				push(@tag,"-");
56372543Sjlemon				if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
564227691Sed					my $tmp_1 = $1;
56514331Speter					my $tmp_;
566274476Skib					foreach $tmp_ (split '\|\|',$tmp_1) {
567274476Skib						$tmp_ =~ /defined\(([^\)]+)\)/;
568102814Siedowse						print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
569162585Snetchild						push(@tag,$1);
570102814Siedowse						$tag{$1}=1;
57114331Speter					}
57214331Speter				} else {
57314331Speter					print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
574177997Skib					print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
575177997Skib					push(@tag,$1);
576177997Skib					$tag{$1}=1;
577283428Sdchagin				}
578177997Skib			} elsif (/^\#\s*error\s+(\w+) is disabled\./) {
579177997Skib				my $tag_i = $#tag;
580227691Sed				while($tag[$tag_i] ne "-") {
581177997Skib					if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
582177997Skib						$tag{$tag[$tag_i]}=2;
583177997Skib						print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
584177997Skib					}
585177997Skib					$tag_i--;
586177997Skib				}
587177997Skib			} elsif (/^\#\s*endif/) {
588227691Sed				my $tag_i = $#tag;
589177997Skib				while($tag_i > 0 && $tag[$tag_i] ne "-") {
590177997Skib					my $t=$tag[$tag_i];
591283428Sdchagin					print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
592177997Skib					if ($tag{$t}==2) {
593177997Skib						$tag{$t}=-1;
594177997Skib					} else {
595177997Skib						$tag{$t}=0;
596177997Skib					}
597177997Skib					print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
59883366Sjulian					pop(@tag);
59914331Speter					if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
600102814Siedowse						$t=$1;
601102814Siedowse					} else {
602162201Snetchild						$t="";
60314331Speter					}
604102814Siedowse					if ($t ne ""
60514331Speter					    && !grep(/^$t$/, @known_algorithms)) {
60614331Speter						$unknown_algorithms{$t} = 1;
60772543Sjlemon						#print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
608102814Siedowse					}
60914331Speter					$tag_i--;
61014331Speter				}
611274476Skib				pop(@tag);
612274476Skib			} elsif (/^\#\s*else/) {
613162201Snetchild				my $tag_i = $#tag;
614274476Skib				while($tag[$tag_i] ne "-") {
615274476Skib					my $t=$tag[$tag_i];
616162201Snetchild					$tag{$t}= -$tag{$t};
617162201Snetchild					print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
618274476Skib					$tag_i--;
619274476Skib				}
620102814Siedowse			} elsif (/^\#\s*if\s+1/) {
621102814Siedowse				push(@tag,"-");
62214331Speter				# Dummy tag
62314331Speter				push(@tag,"TRUE");
62414331Speter				$tag{"TRUE"}=1;
625177997Skib				print STDERR "DEBUG: $file: found 1\n" if $debug;
626177997Skib			} elsif (/^\#\s*if\s+0/) {
627177997Skib				push(@tag,"-");
628177997Skib				# Dummy tag
629177997Skib				push(@tag,"TRUE");
630177997Skib				$tag{"TRUE"}=-1;
631177997Skib				print STDERR "DEBUG: $file: found 0\n" if $debug;
632177997Skib			} elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
633177997Skib				 && $symhacking && $tag{'TRUE'} != -1) {
634177997Skib				# This is for aliasing.  When we find an alias,
635177997Skib				# we have to invert
636177997Skib				&$make_variant($1,$2);
637177997Skib				print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
638177997Skib			}
639177997Skib			if (/^\#/) {
640177997Skib				@current_platforms =
641177997Skib				    grep(!/^$/,
642177997Skib					 map { $tag{$_} == 1 ? $_ :
643177997Skib						   $tag{$_} == -1 ? "!".$_  : "" }
644177997Skib					 @known_platforms);
645202113Smckusick				push @current_platforms
646177997Skib				    , grep(!/^$/,
647177997Skib					   map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
648177997Skib						     $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_  : "" }
649274476Skib					   @known_ossl_platforms);
650177997Skib				@current_algorithms =
651177997Skib				    grep(!/^$/,
652177997Skib					 map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
653177997Skib					 @known_algorithms);
654177997Skib				$def .=
655177997Skib				    "#INFO:"
65683366Sjulian					.join(',',@current_platforms).":"
65714331Speter					    .join(',',@current_algorithms).";";
658102814Siedowse				next;
659102814Siedowse			}
66014331Speter			if ($tag{'TRUE'} != -1) {
661102814Siedowse				if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
66214331Speter					next;
66314331Speter				} elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
66472543Sjlemon					$def .= "int d2i_$3(void);";
665102814Siedowse					$def .= "int i2d_$3(void);";
66614331Speter					# Variant for platforms that do not
667102814Siedowse					# have to access globale variables
668102814Siedowse					# in shared libraries through functions
669102814Siedowse					$def .=
67014331Speter					    "#INFO:"
67114331Speter						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
67214331Speter						    .join(',',@current_algorithms).";";
67383366Sjulian					$def .= "OPENSSL_EXTERN int $2_it;";
67414331Speter					$def .=
675102814Siedowse					    "#INFO:"
676102814Siedowse						.join(',',@current_platforms).":"
67714331Speter						    .join(',',@current_algorithms).";";
678102814Siedowse					# Variant for platforms that have to
67914331Speter					# access globale variables in shared
68014331Speter					# libraries through functions
68172543Sjlemon					&$make_variant("$2_it","$2_it",
682102814Siedowse						      "EXPORT_VAR_AS_FUNCTION",
68314331Speter						      "FUNCTION");
684274476Skib					next;
685274476Skib				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
686102814Siedowse					$def .= "int d2i_$3(void);";
687102814Siedowse					$def .= "int i2d_$3(void);";
68814331Speter					$def .= "int $3_free(void);";
68914331Speter					$def .= "int $3_new(void);";
69014331Speter					# Variant for platforms that do not
691177997Skib					# have to access globale variables
692177997Skib					# in shared libraries through functions
693177997Skib					$def .=
694177997Skib					    "#INFO:"
695177997Skib						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
696177997Skib						    .join(',',@current_algorithms).";";
697177997Skib					$def .= "OPENSSL_EXTERN int $2_it;";
698177997Skib					$def .=
699177997Skib					    "#INFO:"
700177997Skib						.join(',',@current_platforms).":"
701177997Skib						    .join(',',@current_algorithms).";";
702177997Skib					# Variant for platforms that have to
703177997Skib					# access globale variables in shared
704177997Skib					# libraries through functions
705177997Skib					&$make_variant("$2_it","$2_it",
706177997Skib						      "EXPORT_VAR_AS_FUNCTION",
707177997Skib						      "FUNCTION");
708177997Skib					next;
709177997Skib				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
71083366Sjulian					 /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
71114331Speter					$def .= "int d2i_$1(void);";
712102814Siedowse					$def .= "int i2d_$1(void);";
713102814Siedowse					$def .= "int $1_free(void);";
71414331Speter					$def .= "int $1_new(void);";
715102814Siedowse					# Variant for platforms that do not
71614331Speter					# have to access globale variables
71714331Speter					# in shared libraries through functions
71872543Sjlemon					$def .=
719102814Siedowse					    "#INFO:"
72014331Speter						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
721274476Skib						    .join(',',@current_algorithms).";";
722102814Siedowse					$def .= "OPENSSL_EXTERN int $1_it;";
723102814Siedowse					$def .=
72414331Speter					    "#INFO:"
72514331Speter						.join(',',@current_platforms).":"
72614331Speter						    .join(',',@current_algorithms).";";
727177997Skib					# Variant for platforms that have to
728177997Skib					# access globale variables in shared
729177997Skib					# libraries through functions
730177997Skib					&$make_variant("$1_it","$1_it",
731177997Skib						      "EXPORT_VAR_AS_FUNCTION",
732177997Skib						      "FUNCTION");
733177997Skib					next;
734177997Skib				} elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
735177997Skib					$def .= "int d2i_$2(void);";
736177997Skib					$def .= "int i2d_$2(void);";
737177997Skib					# Variant for platforms that do not
738177997Skib					# have to access globale variables
739177997Skib					# in shared libraries through functions
740177997Skib					$def .=
741177997Skib					    "#INFO:"
742177997Skib						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
743177997Skib						    .join(',',@current_algorithms).";";
744177997Skib					$def .= "OPENSSL_EXTERN int $2_it;";
74583366Sjulian					$def .=
74614331Speter					    "#INFO:"
747102814Siedowse						.join(',',@current_platforms).":"
748102814Siedowse						    .join(',',@current_algorithms).";";
74914331Speter					# Variant for platforms that have to
750102814Siedowse					# access globale variables in shared
75114331Speter					# libraries through functions
75214331Speter					&$make_variant("$2_it","$2_it",
75372543Sjlemon						      "EXPORT_VAR_AS_FUNCTION",
754102814Siedowse						      "FUNCTION");
75514331Speter					next;
756274476Skib				} elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
757102814Siedowse					$def .= "int $1_free(void);";
758102814Siedowse					$def .= "int $1_new(void);";
75914331Speter					next;
76014331Speter				} elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
76114331Speter					$def .= "int d2i_$2(void);";
76283366Sjulian					$def .= "int i2d_$2(void);";
76314331Speter					$def .= "int $2_free(void);";
764102814Siedowse					$def .= "int $2_new(void);";
765102814Siedowse					# Variant for platforms that do not
76614331Speter					# have to access globale variables
767102814Siedowse					# in shared libraries through functions
768102814Siedowse					$def .=
769177997Skib					    "#INFO:"
770102814Siedowse						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
771102814Siedowse						    .join(',',@current_algorithms).";";
772102814Siedowse					$def .= "OPENSSL_EXTERN int $2_it;";
773102814Siedowse					$def .=
77414331Speter					    "#INFO:"
77514331Speter						.join(',',@current_platforms).":"
77672543Sjlemon						    .join(',',@current_algorithms).";";
777102814Siedowse					# Variant for platforms that have to
77814331Speter					# access globale variables in shared
779274476Skib					# libraries through functions
780102814Siedowse					&$make_variant("$2_it","$2_it",
781102814Siedowse						      "EXPORT_VAR_AS_FUNCTION",
782102814Siedowse						      "FUNCTION");
78314331Speter					next;
78414331Speter				} elsif (/^\s*DECLARE_ASN1_ITEM\s*\(\s*(\w*)\s*\)/) {
78514331Speter					# Variant for platforms that do not
786177997Skib					# have to access globale variables
787177997Skib					# in shared libraries through functions
788177997Skib					$def .=
789177997Skib					    "#INFO:"
790177997Skib						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
791177997Skib						    .join(',',@current_algorithms).";";
792177997Skib					$def .= "OPENSSL_EXTERN int $1_it;";
793177997Skib					$def .=
794177997Skib					    "#INFO:"
795177997Skib						.join(',',@current_platforms).":"
796177997Skib						    .join(',',@current_algorithms).";";
797177997Skib					# Variant for platforms that have to
798177997Skib					# access globale variables in shared
799177997Skib					# libraries through functions
800177997Skib					&$make_variant("$1_it","$1_it",
801177997Skib						      "EXPORT_VAR_AS_FUNCTION",
802177997Skib						      "FUNCTION");
803177997Skib					next;
804177997Skib				} elsif (/^\s*DECLARE_ASN1_NDEF_FUNCTION\s*\(\s*(\w*)\s*\)/) {
805177997Skib					$def .= "int i2d_$1_NDEF(void);";
806177997Skib				} elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
807177997Skib					next;
808177997Skib				} elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION\s*\(\s*(\w*)\s*\)/) {
809177997Skib					$def .= "int $1_print_ctx(void);";
810177997Skib					next;
811177997Skib				} elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
81283366Sjulian					$def .= "int $2_print_ctx(void);";
81314331Speter					next;
814102814Siedowse				} elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) {
815102814Siedowse					next;
81614331Speter				} elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
817102814Siedowse					 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ||
818102814Siedowse					 /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) {
819177997Skib					# Things not in Win16
820102814Siedowse					$def .=
821102814Siedowse					    "#INFO:"
822102814Siedowse						.join(',',"!WIN16",@current_platforms).":"
823102814Siedowse						    .join(',',@current_algorithms).";";
82414331Speter					$def .= "int PEM_read_$1(void);";
82514331Speter					$def .= "int PEM_write_$1(void);";
82672543Sjlemon					$def .=
827102814Siedowse					    "#INFO:"
82814331Speter						.join(',',@current_platforms).":"
829274476Skib						    .join(',',@current_algorithms).";";
830102814Siedowse					# Things that are everywhere
831102814Siedowse					$def .= "int PEM_read_bio_$1(void);";
832102814Siedowse					$def .= "int PEM_write_bio_$1(void);";
83314331Speter					next;
83414331Speter				} elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
83514331Speter					 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
836177997Skib					# Things not in Win16
837177997Skib					$def .=
838177997Skib					    "#INFO:"
839177997Skib						.join(',',"!WIN16",@current_platforms).":"
840177997Skib						    .join(',',@current_algorithms).";";
841177997Skib					$def .= "int PEM_write_$1(void);";
842177997Skib					$def .=
843177997Skib					    "#INFO:"
844177997Skib						.join(',',@current_platforms).":"
845177997Skib						    .join(',',@current_algorithms).";";
846177997Skib					# Things that are everywhere
847177997Skib					$def .= "int PEM_write_bio_$1(void);";
848177997Skib					next;
849177997Skib				} elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
850177997Skib					 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
851177997Skib					# Things not in Win16
852177997Skib					$def .=
853177997Skib					    "#INFO:"
854177997Skib						.join(',',"!WIN16",@current_platforms).":"
855177997Skib						    .join(',',@current_algorithms).";";
856177997Skib					$def .= "int PEM_read_$1(void);";
857177997Skib					$def .=
858177997Skib					    "#INFO:"
859177997Skib						.join(',',@current_platforms).":"
860177997Skib						    .join(',',@current_algorithms).";";
861177997Skib					# Things that are everywhere
86283366Sjulian					$def .= "int PEM_read_bio_$1(void);";
86314331Speter					next;
864102814Siedowse				} elsif (/^OPENSSL_DECLARE_GLOBAL\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
865102814Siedowse					# Variant for platforms that do not
86614331Speter					# have to access globale variables
867102814Siedowse					# in shared libraries through functions
86814331Speter					$def .=
86914331Speter					    "#INFO:"
87072543Sjlemon						.join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
871102814Siedowse						    .join(',',@current_algorithms).";";
872102814Siedowse					$def .= "OPENSSL_EXTERN int _shadow_$2;";
87314331Speter					$def .=
874274476Skib					    "#INFO:"
875274476Skib						.join(',',@current_platforms).":"
876102814Siedowse						    .join(',',@current_algorithms).";";
877102814Siedowse					# Variant for platforms that have to
87814331Speter					# access globale variables in shared
87914331Speter					# libraries through functions
88014331Speter					&$make_variant("_shadow_$2","_shadow_$2",
881177997Skib						      "EXPORT_VAR_AS_FUNCTION",
882177997Skib						      "FUNCTION");
883177997Skib				} elsif ($tag{'CONST_STRICT'} != 1) {
884177997Skib					if (/\{|\/\*|\([^\)]*$/) {
885177997Skib						$line = $_;
886177997Skib					} else {
887177997Skib						$def .= $_;
888177997Skib					}
889177997Skib				}
890177997Skib			}
891177997Skib		}
892177997Skib		close(IN);
893177997Skib
894177997Skib		my $algs;
895177997Skib		my $plays;
896177997Skib
897177997Skib		print STDERR "DEBUG: postprocessing ----------\n" if $debug;
898177997Skib		foreach (split /;/, $def) {
899177997Skib			my $s; my $k = "FUNCTION"; my $p; my $a;
900178439Srdivacky			s/^[\n\s]*//g;
901177997Skib			s/[\n\s]*$//g;
90283366Sjulian			next if(/\#undef/);
90314331Speter			next if(/typedef\W/);
904102814Siedowse			next if(/\#define/);
905102814Siedowse
90614331Speter			# Reduce argument lists to empty ()
907102814Siedowse			# fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
90814331Speter			while(/\(.*\)/s) {
90914331Speter				s/\([^\(\)]+\)/\{\}/gs;
91072543Sjlemon				s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs;	#(*f{}) -> f
911102814Siedowse			}
91214331Speter			# pretend as we didn't use curly braces: {} -> ()
91314331Speter			s/\{\}/\(\)/gs;
914102814Siedowse
915102814Siedowse			s/STACK_OF\(\)/void/gs;
916102814Siedowse			s/LHASH_OF\(\)/void/gs;
91714331Speter
91814331Speter			print STDERR "DEBUG: \$_ = \"$_\"\n" if $debug;
919283415Sdchagin			if (/^\#INFO:([^:]*):(.*)$/) {
92049662Smarcel				$plats = $1;
921178439Srdivacky				$algs = $2;
922178439Srdivacky				print STDERR "DEBUG: found info on platforms ($plats) and algorithms ($algs)\n" if $debug;
923178439Srdivacky				next;
924178439Srdivacky			} elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+(\{[0-9]+\})?)(\[[0-9]*\])*\s*$/) {
925178439Srdivacky				$s = $1;
926178439Srdivacky				$k = "VARIABLE";
927178439Srdivacky				print STDERR "DEBUG: found external variable $s\n" if $debug;
928178439Srdivacky			} elsif (/TYPEDEF_\w+_OF/s) {
929178439Srdivacky				next;
930178439Srdivacky			} elsif (/(\w+)\s*\(\).*/s) {	# first token prior [first] () is
931178439Srdivacky				$s = $1;		# a function name!
932178439Srdivacky				print STDERR "DEBUG: found function $s\n" if $debug;
933178439Srdivacky			} elsif (/\(/ and not (/=/)) {
934178439Srdivacky				print STDERR "File $file: cannot parse: $_;\n";
935178439Srdivacky				next;
936178439Srdivacky			} else {
937283415Sdchagin				next;
938283415Sdchagin			}
939178439Srdivacky
940156842Snetchild			$syms{$s} = 1;
941156842Snetchild			$kind{$s} = $k;
942156842Snetchild
943156842Snetchild			$p = $plats;
944156842Snetchild			$a = $algs;
945156842Snetchild			$a .= ",BF" if($s =~ /EVP_bf/);
946156842Snetchild			$a .= ",CAST" if($s =~ /EVP_cast/);
947300411Sdchagin			$a .= ",DES" if($s =~ /EVP_des/);
948156842Snetchild			$a .= ",DSA" if($s =~ /EVP_dss/);
949156842Snetchild			$a .= ",IDEA" if($s =~ /EVP_idea/);
950225617Skmacy			$a .= ",MD2" if($s =~ /EVP_md2/);
951156842Snetchild			$a .= ",MD4" if($s =~ /EVP_md4/);
952156842Snetchild			$a .= ",MD5" if($s =~ /EVP_md5/);
953156842Snetchild			$a .= ",RC2" if($s =~ /EVP_rc2/);
95483366Sjulian			$a .= ",RC4" if($s =~ /EVP_rc4/);
95549662Smarcel			$a .= ",RC5" if($s =~ /EVP_rc5/);
956102814Siedowse			$a .= ",RIPEMD" if($s =~ /EVP_ripemd/);
957102814Siedowse			$a .= ",SHA" if($s =~ /EVP_sha/);
95849662Smarcel			$a .= ",RSA" if($s =~ /EVP_(Open|Seal)(Final|Init)/);
959102814Siedowse			$a .= ",RSA" if($s =~ /PEM_Seal(Final|Init|Update)/);
960102814Siedowse			$a .= ",RSA" if($s =~ /RSAPrivateKey/);
961177997Skib			$a .= ",RSA" if($s =~ /SSLv23?_((client|server)_)?method/);
962102814Siedowse
963102814Siedowse			$platform{$s} =
964102814Siedowse			    &reduce_platforms((defined($platform{$s})?$platform{$s}.',':"").$p);
965102814Siedowse			$algorithm{$s} .= ','.$a;
96649662Smarcel
96749662Smarcel			if (defined($variant{$s})) {
96872543Sjlemon				foreach $v (split /;/,$variant{$s}) {
969102814Siedowse					(my $r, my $p, my $k) = split(/:/,$v);
97049662Smarcel					my $ip = join ',',map({ /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p);
971274476Skib					$syms{$r} = 1;
972274476Skib					if (!defined($k)) { $k = $kind{$s}; }
973102814Siedowse					$kind{$r} = $k."(".$s.")";
974102814Siedowse					$algorithm{$r} = $algorithm{$s};
975102814Siedowse					$platform{$r} = &reduce_platforms($platform{$s}.",".$p.",".$p);
97649662Smarcel					$platform{$s} = &reduce_platforms($platform{$s}.','.$ip.','.$ip);
97749788Smarcel					print STDERR "DEBUG: \$variant{\"$s\"} = ",$v,"; \$r = $r; \$p = ",$platform{$r},"; \$a = ",$algorithm{$r},"; \$kind = ",$kind{$r},"\n" if $debug;
97853713Smarcel				}
979177997Skib			}
980177997Skib			print STDERR "DEBUG: \$s = $s; \$p = ",$platform{$s},"; \$a = ",$algorithm{$s},"; \$kind = ",$kind{$s},"\n" if $debug;
981177997Skib		}
982227693Sed	}
983177997Skib
984227693Sed	# Prune the returned symbols
985177997Skib
986177997Skib        delete $syms{"bn_dump1"};
987177997Skib	$platform{"BIO_s_log"} .= ",!WIN32,!WIN16,!macintosh";
988177997Skib
989177997Skib	$platform{"PEM_read_NS_CERT_SEQ"} = "VMS";
990177997Skib	$platform{"PEM_write_NS_CERT_SEQ"} = "VMS";
991177997Skib	$platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
992177997Skib	$platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
993177997Skib	$platform{"EVP_sha384"} = "!VMSVAX";
994177997Skib	$platform{"EVP_sha512"} = "!VMSVAX";
995177997Skib	$platform{"SHA384_Init"} = "!VMSVAX";
996177997Skib	$platform{"SHA384_Transform"} = "!VMSVAX";
997177997Skib	$platform{"SHA384_Update"} = "!VMSVAX";
998177997Skib	$platform{"SHA384_Final"} = "!VMSVAX";
999177997Skib	$platform{"SHA384"} = "!VMSVAX";
1000227693Sed	$platform{"SHA512_Init"} = "!VMSVAX";
1001177997Skib	$platform{"SHA512_Transform"} = "!VMSVAX";
1002177997Skib	$platform{"SHA512_Update"} = "!VMSVAX";
1003227693Sed	$platform{"SHA512_Final"} = "!VMSVAX";
1004227693Sed	$platform{"SHA512"} = "!VMSVAX";
1005227693Sed	$platform{"WHIRLPOOL_Init"} = "!VMSVAX";
1006177997Skib	$platform{"WHIRLPOOL"} = "!VMSVAX";
1007177997Skib	$platform{"WHIRLPOOL_BitUpdate"} = "!VMSVAX";
1008177997Skib	$platform{"EVP_whirlpool"} = "!VMSVAX";
1009177997Skib	$platform{"WHIRLPOOL_Final"} = "!VMSVAX";
1010177997Skib	$platform{"WHIRLPOOL_Update"} = "!VMSVAX";
1011177997Skib
101283366Sjulian
101383366Sjulian	# Info we know about
101453713Smarcel
101553713Smarcel	push @ret, map { $_."\\".&info_string($_,"EXIST",
101653713Smarcel					      $platform{$_},
1017304987Skib					      $kind{$_},
101853713Smarcel					      $algorithm{$_}) } keys %syms;
101963285Smarcel
102063285Smarcel	if (keys %unknown_algorithms) {
102183366Sjulian		print STDERR "WARNING: mkdef.pl doesn't know the following algorithms:\n";
102283366Sjulian		print STDERR "\t",join("\n\t",keys %unknown_algorithms),"\n";
102363285Smarcel	}
102463285Smarcel	return(@ret);
102563285Smarcel}
1026255219Spjd
1027162585Snetchild# Param: string of comma-separated platform-specs.
1028162585Snetchildsub reduce_platforms
102963285Smarcel{
103063285Smarcel	my ($platforms) = @_;
103163285Smarcel	my $pl = defined($platforms) ? $platforms : "";
103263285Smarcel	my %p = map { $_ => 0 } split /,/, $pl;
103363285Smarcel	my $ret;
1034225617Skmacy
1035162585Snetchild	print STDERR "DEBUG: Entered reduce_platforms with \"$platforms\"\n"
1036247602Spjd	    if $debug;
1037255219Spjd	# We do this, because if there's code like the following, it really
1038255219Spjd	# means the function exists in all cases and should therefore be
1039255219Spjd	# everywhere.  By increasing and decreasing, we may attain 0:
1040247602Spjd	#
1041162585Snetchild	# ifndef WIN16
1042247602Spjd	#    int foo();
1043162585Snetchild	# else
1044162585Snetchild	#    int _fat foo();
1045162585Snetchild	# endif
1046162585Snetchild	foreach $platform (split /,/, $pl) {
1047162585Snetchild		if ($platform =~ /^!(.*)$/) {
104863285Smarcel			$p{$1}--;
104963285Smarcel		} else {
105063285Smarcel			$p{$platform}++;
105183366Sjulian		}
105283366Sjulian	}
105363285Smarcel	foreach $platform (keys %p) {
105463285Smarcel		if ($p{$platform} == 0) { delete $p{$platform}; }
105563285Smarcel	}
105663285Smarcel
105763285Smarcel	delete $p{""};
105863285Smarcel
105963285Smarcel	$ret = join(',',sort(map { $p{$_} < 0 ? "!".$_ : $_ } keys %p));
106063285Smarcel	print STDERR "DEBUG: Exiting reduce_platforms with \"$ret\"\n"
1061300411Sdchagin	    if $debug;
106263285Smarcel	return $ret;
106372538Sjlemon}
106472538Sjlemon
106583366Sjuliansub info_string {
106672538Sjlemon	(my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_;
1067111798Sdes
1068111798Sdes	my %a = defined($algorithms) ?
106973286Sadrian	    map { $_ => 1 } split /,/, $algorithms : ();
107073286Sadrian	my $k = defined($kind) ? $kind : "FUNCTION";
107172538Sjlemon	my $ret;
1072111798Sdes	my $p = &reduce_platforms($platforms);
107373286Sadrian
107472538Sjlemon	delete $a{""};
1075111798Sdes
1076127057Stjr	$ret = $exist;
107772538Sjlemon	$ret .= ":".$p;
1078111798Sdes	$ret .= ":".$k;
1079127057Stjr	$ret .= ":".join(',',sort keys %a);
108072538Sjlemon	return $ret;
1081111798Sdes}
108272538Sjlemon
108372538Sjlemonsub maybe_add_info {
108472538Sjlemon	(my $name, *nums, my @symbols) = @_;
108572538Sjlemon	my $sym;
108672538Sjlemon	my $new_info = 0;
108772538Sjlemon	my %syms=();
108872538Sjlemon
108972538Sjlemon	print STDERR "Updating $name info\n";
1090127059Stjr	foreach $sym (@symbols) {
109172538Sjlemon		(my $s, my $i) = split /\\/, $sym;
1092127059Stjr		if (defined($nums{$s})) {
1093190445Sambrisko			$i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/;
1094190445Sambrisko			(my $n, my $dummy) = split /\\/, $nums{$s};
109572538Sjlemon			if (!defined($dummy) || $i ne $dummy) {
109672538Sjlemon				$nums{$s} = $n."\\".$i;
109773286Sadrian				$new_info++;
109872538Sjlemon				print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n" if $debug;
109972538Sjlemon			}
110072538Sjlemon		}
110172538Sjlemon		$syms{$s} = 1;
110272538Sjlemon	}
110372538Sjlemon
110472538Sjlemon	my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums;
1105111798Sdes	foreach $sym (@s) {
110672538Sjlemon		(my $n, my $i) = split /\\/, $nums{$sym};
1107111798Sdes		if (!defined($syms{$sym}) && $i !~ /^NOEXIST:/) {
110872538Sjlemon			$new_info++;
1109111798Sdes			print STDERR "DEBUG: maybe_add_info for $sym: -> undefined\n" if $debug;
111072538Sjlemon		}
1111111798Sdes	}
111272538Sjlemon	if ($new_info) {
111372538Sjlemon		print STDERR "$new_info old symbols got an info update\n";
1114281689Strasz		if (!$do_rewrite) {
1115281689Strasz			print STDERR "You should do a rewrite to fix this.\n";
1116281689Strasz		}
1117281689Strasz	} else {
1118281689Strasz		print STDERR "No old symbols needed info update\n";
1119127059Stjr	}
112072538Sjlemon}
112172538Sjlemon
1122283415Sdchagin# Param: string of comma-separated keywords, each possibly prefixed with a "!"
112372538Sjlemonsub is_valid
112483366Sjulian{
112572538Sjlemon	my ($keywords_txt,$platforms) = @_;
112683221Smarcel	my (@keywords) = split /,/,$keywords_txt;
112772538Sjlemon	my ($falsesum, $truesum) = (0, 1);
112872538Sjlemon
112972538Sjlemon	# Param: one keyword
113083366Sjulian	sub recognise
113172538Sjlemon	{
1132283415Sdchagin		my ($keyword,$platforms) = @_;
113372538Sjlemon
113472538Sjlemon		if ($platforms) {
113583366Sjulian			# platforms
113672538Sjlemon			if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
113772538Sjlemon			if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
113872538Sjlemon			if ($keyword eq "VMS" && $VMS) { return 1; }
113972538Sjlemon			if ($keyword eq "WIN32" && $W32) { return 1; }
114072538Sjlemon			if ($keyword eq "WIN16" && $W16) { return 1; }
1141225617Skmacy			if ($keyword eq "WINNT" && $NT) { return 1; }
114272538Sjlemon			if ($keyword eq "OS2" && $OS2) { return 1; }
114383221Smarcel			# Special platforms:
114483221Smarcel			# EXPORT_VAR_AS_FUNCTION means that global variables
114583221Smarcel			# will be represented as functions.  This currently
114683221Smarcel			# only happens on VMS-VAX.
114783221Smarcel			if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32 || $W16)) {
114883221Smarcel				return 1;
114983221Smarcel			}
115083221Smarcel			if ($keyword eq "OPENSSL_FIPS" && $fips) {
115183221Smarcel				return 1;
115283221Smarcel			}
115383221Smarcel			if ($keyword eq "ZLIB" && $zlib) { return 1; }
1154133816Stjr			return 0;
1155140214Sobrien		} else {
1156133816Stjr			# algorithms
1157133816Stjr			if ($keyword eq "RC2" && $no_rc2) { return 0; }
1158133816Stjr			if ($keyword eq "RC4" && $no_rc4) { return 0; }
115983221Smarcel			if ($keyword eq "RC5" && $no_rc5) { return 0; }
116083221Smarcel			if ($keyword eq "IDEA" && $no_idea) { return 0; }
116183221Smarcel			if ($keyword eq "DES" && $no_des) { return 0; }
116283221Smarcel			if ($keyword eq "BF" && $no_bf) { return 0; }
116383221Smarcel			if ($keyword eq "CAST" && $no_cast) { return 0; }
116483221Smarcel			if ($keyword eq "MD2" && $no_md2) { return 0; }
116583221Smarcel			if ($keyword eq "MD4" && $no_md4) { return 0; }
116683221Smarcel			if ($keyword eq "MD5" && $no_md5) { return 0; }
116783221Smarcel			if ($keyword eq "SHA" && $no_sha) { return 0; }
116883221Smarcel			if ($keyword eq "RIPEMD" && $no_ripemd) { return 0; }
116983221Smarcel			if ($keyword eq "MDC2" && $no_mdc2) { return 0; }
117083221Smarcel			if ($keyword eq "WHIRLPOOL" && $no_whirlpool) { return 0; }
117183221Smarcel			if ($keyword eq "RSA" && $no_rsa) { return 0; }
117283221Smarcel			if ($keyword eq "DSA" && $no_dsa) { return 0; }
117383221Smarcel			if ($keyword eq "DH" && $no_dh) { return 0; }
117483221Smarcel			if ($keyword eq "EC" && $no_ec) { return 0; }
117583221Smarcel			if ($keyword eq "ECDSA" && $no_ecdsa) { return 0; }
117683221Smarcel			if ($keyword eq "ECDH" && $no_ecdh) { return 0; }
117783221Smarcel			if ($keyword eq "HMAC" && $no_hmac) { return 0; }
117883221Smarcel			if ($keyword eq "AES" && $no_aes) { return 0; }
117983221Smarcel			if ($keyword eq "CAMELLIA" && $no_camellia) { return 0; }
118083221Smarcel			if ($keyword eq "SEED" && $no_seed) { return 0; }
1181177633Sdfr			if ($keyword eq "EVP" && $no_evp) { return 0; }
118283221Smarcel			if ($keyword eq "LHASH" && $no_lhash) { return 0; }
118383221Smarcel			if ($keyword eq "STACK" && $no_stack) { return 0; }
118483221Smarcel			if ($keyword eq "ERR" && $no_err) { return 0; }
118583221Smarcel			if ($keyword eq "BUFFER" && $no_buffer) { return 0; }
118683221Smarcel			if ($keyword eq "BIO" && $no_bio) { return 0; }
118783221Smarcel			if ($keyword eq "COMP" && $no_comp) { return 0; }
118883221Smarcel			if ($keyword eq "DSO" && $no_dso) { return 0; }
118983221Smarcel			if ($keyword eq "KRB5" && $no_krb5) { return 0; }
119083221Smarcel			if ($keyword eq "ENGINE" && $no_engine) { return 0; }
119183221Smarcel			if ($keyword eq "HW" && $no_hw) { return 0; }
119283221Smarcel			if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
119383221Smarcel			if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
119483221Smarcel			if ($keyword eq "GMP" && $no_gmp) { return 0; }
119583221Smarcel			if ($keyword eq "RFC3779" && $no_rfc3779) { return 0; }
119683221Smarcel			if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; }
119783221Smarcel			if ($keyword eq "PSK" && $no_psk) { return 0; }
119883221Smarcel			if ($keyword eq "CMS" && $no_cms) { return 0; }
119983221Smarcel			if ($keyword eq "EC2M" && $no_ec2m) { return 0; }
120083221Smarcel			if ($keyword eq "NEXTPROTONEG" && $no_nextprotoneg) { return 0; }
120183221Smarcel			if ($keyword eq "EC_NISTP_64_GCC_128" && $no_nistp_gcc)
120283221Smarcel					{ return 0; }
120383221Smarcel			if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
1204140214Sobrien			if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
120583221Smarcel			if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
120683221Smarcel			if ($keyword eq "SRP" && $no_srp) { return 0; }
120783221Smarcel			if ($keyword eq "SCTP" && $no_sctp) { return 0; }
120883221Smarcel			if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
120983221Smarcel
121083221Smarcel			# Nothing recognise as true
1211133816Stjr			return 1;
1212140214Sobrien		}
1213133816Stjr	}
1214133816Stjr
1215133816Stjr	foreach $k (@keywords) {
121683221Smarcel		if ($k =~ /^!(.*)$/) {
121783221Smarcel			$falsesum += &recognise($1,$platforms);
121883221Smarcel		} else {
121983221Smarcel			$truesum *= &recognise($k,$platforms);
122083221Smarcel		}
122183221Smarcel	}
122283221Smarcel	print STDERR "DEBUG: [",$#keywords,",",$#keywords < 0,"] is_valid($keywords_txt) => (\!$falsesum) && $truesum = ",(!$falsesum) && $truesum,"\n" if $debug;
122383221Smarcel	return (!$falsesum) && $truesum;
122483221Smarcel}
122583221Smarcel
122683221Smarcelsub print_test_file
122783221Smarcel{
122883221Smarcel	(*OUT,my $name,*nums,my $testall,my @symbols)=@_;
122983221Smarcel	my $n = 1; my @e; my @r;
123083221Smarcel	my $sym; my $prev = ""; my $prefSSLeay;
123183221Smarcel
123283221Smarcel	(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
123383221Smarcel	(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:.*/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
123483221Smarcel	@symbols=((sort @e),(sort @r));
123583221Smarcel
123683221Smarcel	foreach $sym (@symbols) {
123783221Smarcel		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1238177633Sdfr		my $v = 0;
123983221Smarcel		$v = 1 if $i=~ /^.*?:.*?:VARIABLE/;
124083221Smarcel		my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
124183221Smarcel		my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
124283221Smarcel		if (!defined($nums{$s})) {
124383221Smarcel			print STDERR "Warning: $s does not have a number assigned\n"
124483221Smarcel			    if(!$do_update);
124583221Smarcel		} elsif (is_valid($p,1) && is_valid($a,0)) {
124683221Smarcel			my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
124783221Smarcel			if ($prev eq $s2) {
124883221Smarcel				print OUT "\t/* The following has already appeared previously */\n";
124983221Smarcel				print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
125083221Smarcel			}
125183221Smarcel			$prev = $s2;	# To warn about duplicates...
125283221Smarcel
125383221Smarcel			($nn,$ni)=($nums{$s2} =~ /^(.*?)\\(.*)$/);
125483221Smarcel			if ($v) {
125583221Smarcel				print OUT "\textern int $s2; /* type unknown */ /* $nn $ni */\n";
125683221Smarcel			} else {
125783221Smarcel				print OUT "\textern int $s2(); /* type unknown */ /* $nn $ni */\n";
125883221Smarcel			}
125983221Smarcel		}
1260133816Stjr	}
126183221Smarcel}
126283221Smarcel
1263283415Sdchaginsub get_version {
126483221Smarcel   local *MF;
1265107680Siedowse   my $v = '?';
1266107680Siedowse   open MF, 'Makefile' or return $v;
1267255219Spjd   while (<MF>) {
126883221Smarcel     $v = $1, last if /^VERSION=(.*?)\s*$/;
1269102872Siedowse   }
127083221Smarcel   close MF;
127183221Smarcel   return $v;
127283221Smarcel}
127383221Smarcel
1274102872Siedowsesub print_def_file
127583221Smarcel{
127683221Smarcel	(*OUT,my $name,*nums,my @symbols)=@_;
1277102872Siedowse	my $n = 1; my @e; my @r; my @v; my $prev="";
127883221Smarcel	my $liboptions="";
127983221Smarcel	my $libname = $name;
1280102872Siedowse	my $http_vendor = 'www.openssl.org/';
128183221Smarcel	my $version = get_version();
128283221Smarcel	my $what = "OpenSSL: implementation of Secure Socket Layer";
1283102872Siedowse	my $description = "$what $version, $name - http://$http_vendor";
128483366Sjulian
128583366Sjulian	if ($W32)
128683221Smarcel		{ $libname.="32"; }
128783366Sjulian	elsif ($W16)
128883221Smarcel		{ $libname.="16"; }
128983366Sjulian	elsif ($OS2)
129083221Smarcel		{ # DLL names should not clash on the whole system.
129183366Sjulian		  # However, they should not have any particular relationship
129283221Smarcel		  # to the name of the static library.  Chose descriptive names
129383366Sjulian		  # (must be at most 8 chars).
129483221Smarcel		  my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
129583366Sjulian		  $libname = $translate{$name} || $name;
129683221Smarcel		  $liboptions = <<EOO;
129783366SjulianINITINSTANCE
129883221SmarcelDATA MULTIPLE NONSHARED
129983366SjulianEOO
1300144987Smdodd		  # Vendor field can't contain colon, drat; so we omit http://
1301144987Smdodd		  $description = "\@#$http_vendor:$version#\@$what; DLL for library $name.  Build for EMX -Zmtd";
1302144987Smdodd		}
1303144987Smdodd
1304144987Smdodd	print OUT <<"EOF";
1305144987Smdodd;
1306144987Smdodd; Definition file for the DLL version of the $name library from OpenSSL
1307144987Smdodd;
130883221Smarcel
130983221SmarcelLIBRARY         $libname	$liboptions
131083221Smarcel
1311102872SiedowseEOF
131283221Smarcel
1313102872Siedowse	if ($W16) {
131483221Smarcel		print <<"EOF";
1315102872SiedowseCODE            PRELOAD MOVEABLE
131683221SmarcelDATA            PRELOAD MOVEABLE SINGLE
1317102872Siedowse
131883221SmarcelEXETYPE		WINDOWS
1319102872Siedowse
1320144987SmdoddHEAPSIZE	4096
1321144987SmdoddSTACKSIZE	8192
1322144987Smdodd
1323144987SmdoddEOF
1324144987Smdodd	}
1325144987Smdodd
1326144987Smdodd	print "EXPORTS\n";
1327144987Smdodd
1328102872Siedowse	(@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
132983221Smarcel	(@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
1330107680Siedowse	(@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
1331111797Sdes	@symbols=((sort @e),(sort @r), (sort @v));
1332107680Siedowse
1333107680Siedowse
1334107680Siedowse	foreach $sym (@symbols) {
1335107680Siedowse		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1336107680Siedowse		my $v = 0;
1337107680Siedowse		$v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
1338107680Siedowse		if (!defined($nums{$s})) {
1339107680Siedowse			printf STDERR "Warning: $s does not have a number assigned\n"
1340111797Sdes			    if(!$do_update);
1341107680Siedowse		} else {
1342107680Siedowse			(my $n, my $dummy) = split /\\/, $nums{$s};
1343107680Siedowse			my %pf = ();
1344111797Sdes			my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1345107680Siedowse			my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1346107680Siedowse			if (is_valid($p,1) && is_valid($a,0)) {
1347107680Siedowse				my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1348107680Siedowse				if ($prev eq $s2) {
1349107680Siedowse					print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1350107680Siedowse				}
1351107680Siedowse				$prev = $s2;	# To warn about duplicates...
1352107680Siedowse				if($v && !$OS2) {
1353111797Sdes					printf OUT "    %s%-39s @%-8d DATA\n",($W32)?"":"_",$s2,$n;
1354107680Siedowse				} else {
1355107680Siedowse					printf OUT "    %s%-39s @%d\n",($W32||$OS2)?"":"_",$s2,$n;
1356107680Siedowse				}
1357107680Siedowse			}
1358107680Siedowse		}
1359107680Siedowse	}
1360107680Siedowse	printf OUT "\n";
136183221Smarcel}
1362102872Siedowse
136383221Smarcelsub load_numbers
136483221Smarcel{
136583221Smarcel	my($name)=@_;
136683221Smarcel	my(@a,%ret);
136783221Smarcel
136883221Smarcel	$max_num = 0;
136983221Smarcel	$num_noinfo = 0;
1370255219Spjd	$prev = "";
1371255219Spjd	$prev_cnt = 0;
137289319Salfred
137389319Salfred	open(IN,"<$name") || die "unable to open $name:$!\n";
137489306Salfred	while (<IN>) {
137589306Salfred		chop;
137683221Smarcel		s/#.*$//;
137789306Salfred		next if /^\s*$/;
137889306Salfred		@a=split;
137983221Smarcel		if (defined $ret{$a[0]}) {
1380102872Siedowse			# This is actually perfectly OK
1381283439Sdchagin			#print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n";
1382283439Sdchagin		}
1383283439Sdchagin		if ($max_num > $a[1]) {
138483221Smarcel			print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n";
138583221Smarcel		}
138683221Smarcel		elsif ($max_num == $a[1]) {
138783221Smarcel			# This is actually perfectly OK
138883221Smarcel			#print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n";
138983221Smarcel			if ($a[0] eq $prev) {
139083366Sjulian				$prev_cnt++;
139183221Smarcel				$a[0] .= "{$prev_cnt}";
139283221Smarcel			}
139383221Smarcel		}
139483221Smarcel		else {
139583221Smarcel			$prev_cnt = 0;
139683221Smarcel		}
139783221Smarcel		if ($#a < 2) {
1398283415Sdchagin			# Existence will be proven later, in do_defs
139983221Smarcel			$ret{$a[0]}=$a[1];
140083221Smarcel			$num_noinfo++;
1401140214Sobrien		} else {
140283221Smarcel			$ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker
140383366Sjulian		}
140483221Smarcel		$max_num = $a[1] if $a[1] > $max_num;
140583221Smarcel		$prev=$a[0];
1406102872Siedowse	}
1407283415Sdchagin	if ($num_noinfo) {
140883221Smarcel		print STDERR "Warning: $num_noinfo symbols were without info.";
140983221Smarcel		if ($do_rewrite) {
141083221Smarcel			printf STDERR "  The rewrite will fix this.\n";
141183221Smarcel		} else {
141283221Smarcel			printf STDERR "  You should do a rewrite to fix this.\n";
141383221Smarcel		}
141483221Smarcel	}
141583221Smarcel	close(IN);
141699687Srobert	return(%ret);
1417111797Sdes}
141883221Smarcel
141983221Smarcelsub parse_number
142083221Smarcel{
1421102872Siedowse	(my $str, my $what) = @_;
1422102872Siedowse	(my $n, my $i) = split(/\\/,$str);
142383221Smarcel	if ($what eq "n") {
142483221Smarcel		return $n;
1425102872Siedowse	} else {
1426111797Sdes		return $i;
1427111797Sdes	}
142883221Smarcel}
142999687Srobert
1430111797Sdessub rewrite_numbers
143183221Smarcel{
143283221Smarcel	(*OUT,$name,*nums,@symbols)=@_;
143383221Smarcel	my $thing;
1434102872Siedowse
1435102872Siedowse	print STDERR "Rewriting $name\n";
1436102872Siedowse
143783221Smarcel	my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
143899687Srobert	my $r; my %r; my %rsyms;
1439111797Sdes	foreach $r (@r) {
144083221Smarcel		(my $s, my $i) = split /\\/, $r;
144183221Smarcel		my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
144283221Smarcel		$i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1443102872Siedowse		$r{$a} = $s."\\".$i;
1444102872Siedowse		$rsyms{$s} = 1;
1445102872Siedowse	}
144683221Smarcel
144783221Smarcel	my %syms = ();
1448283415Sdchagin	foreach $_ (@symbols) {
1449283415Sdchagin		(my $n, my $i) = split /\\/;
1450283415Sdchagin		$syms{$n} = 1;
1451283415Sdchagin	}
145283221Smarcel
1453133816Stjr	my @s=sort {
145485022Smarcel	    &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n")
145585022Smarcel	    || $a cmp $b
145685022Smarcel	} keys %nums;
145785022Smarcel	foreach $sym (@s) {
1458102814Siedowse		(my $n, my $i) = split /\\/, $nums{$sym};
1459102814Siedowse		next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/;
146085022Smarcel		next if defined($rsyms{$sym});
1461102814Siedowse		print STDERR "DEBUG: rewrite_numbers for sym = ",$sym,": i = ",$i,", n = ",$n,", rsym{sym} = ",$rsyms{$sym},"syms{sym} = ",$syms{$sym},"\n" if $debug;
146285022Smarcel		$i="NOEXIST::FUNCTION:"
146385022Smarcel			if !defined($i) || $i eq "" || !defined($syms{$sym});
146485022Smarcel		my $s2 = $sym;
1465102814Siedowse		$s2 =~ s/\{[0-9]+\}$//;
146685022Smarcel		printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
1467274476Skib		if (exists $r{$sym}) {
1468274476Skib			(my $s, $i) = split /\\/,$r{$sym};
1469102814Siedowse			my $s2 = $s;
1470102814Siedowse			$s2 =~ s/\{[0-9]+\}$//;
147185022Smarcel			printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
147285022Smarcel		}
147385022Smarcel	}
1474177997Skib}
1475177997Skib
1476177997Skibsub update_numbers
1477227693Sed{
1478177997Skib	(*OUT,$name,*nums,my $start_num, my @symbols)=@_;
1479177997Skib	my $new_syms = 0;
1480177997Skib
1481177997Skib	print STDERR "Updating $name numbers\n";
1482177997Skib
1483177997Skib	my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
1484177997Skib	my $r; my %r; my %rsyms;
1485177997Skib	foreach $r (@r) {
1486177997Skib		(my $s, my $i) = split /\\/, $r;
1487177997Skib		my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1488177997Skib		$i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1489177997Skib		$r{$a} = $s."\\".$i;
1490227693Sed		$rsyms{$s} = 1;
1491177997Skib	}
1492177997Skib
1493227693Sed	foreach $sym (@symbols) {
1494177997Skib		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1495177997Skib		next if $i =~ /^.*?:.*?:\w+\(\w+\)/;
1496177997Skib		next if defined($rsyms{$sym});
1497177997Skib		die "ERROR: Symbol $sym had no info attached to it."
1498177997Skib		    if $i eq "";
149985022Smarcel		if (!exists $nums{$s}) {
150085022Smarcel			$new_syms++;
1501102814Siedowse			my $s2 = $s;
1502102814Siedowse			$s2 =~ s/\{[0-9]+\}$//;
150385022Smarcel			printf OUT "%s%-39s %d\t%s\n","",$s2, ++$start_num,$i;
1504102814Siedowse			if (exists $r{$s}) {
150585022Smarcel				($s, $i) = split /\\/,$r{$s};
150685022Smarcel				$s =~ s/\{[0-9]+\}$//;
150785022Smarcel				printf OUT "%s%-39s %d\t%s\n","",$s, $start_num,$i;
1508102814Siedowse			}
150985022Smarcel		}
1510274476Skib	}
1511274476Skib	if($new_syms) {
1512102814Siedowse		print STDERR "$new_syms New symbols added\n";
1513102814Siedowse	} else {
151485022Smarcel		print STDERR "No New symbols Added\n";
1515228957Sjhb	}
1516228957Sjhb}
1517228957Sjhb
1518228957Sjhbsub check_existing
1519228957Sjhb{
1520228957Sjhb	(*nums, my @symbols)=@_;
1521228957Sjhb	my %existing; my @remaining;
1522228957Sjhb	@remaining=();
1523228957Sjhb	foreach $sym (@symbols) {
1524228957Sjhb		(my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1525228957Sjhb		$existing{$s}=1;
1526228957Sjhb	}
1527228957Sjhb	foreach $sym (keys %nums) {
1528228957Sjhb		if (!exists $existing{$sym}) {
1529228957Sjhb			push @remaining, $sym;
1530228957Sjhb		}
1531228957Sjhb	}
1532228957Sjhb	if(@remaining) {
1533228957Sjhb		print STDERR "The following symbols do not seem to exist:\n";
1534228957Sjhb		foreach $sym (@remaining) {
1535228957Sjhb			print STDERR "\t",$sym,"\n";
1536228957Sjhb		}
1537228957Sjhb	}
1538228957Sjhb}
1539228957Sjhb
1540228957Sjhb