]> git.ipfire.org Git - thirdparty/openssl.git/blame - util/mkdef.pl
Add forgotten change of check of disabled-dynamic-engine
[thirdparty/openssl.git] / util / mkdef.pl
CommitLineData
ce9449cf 1#!/usr/local/bin/perl -w
d02b48c6
RE
2#
3# generate a .def file
4#
5# It does this by parsing the header files and looking for the
47339f61 6# prototyped functions: it then prunes the output.
d02b48c6 7#
1a53f1d6
RS
8# Intermediary files are created, call libeay.num and ssleay.num,
9# The format of these files is:
948d0125 10#
e863d920 11# routine-name nnnn vers info
948d0125 12#
e863d920
MC
13# The "nnnn" and "vers" fields are the numeric id and version for the symbol
14# respectively. The "info" part is actually a colon-separated string of fields
15# with the following meaning:
948d0125
RL
16#
17# existence:platform:kind:algorithms
18#
19# - "existence" can be "EXIST" or "NOEXIST" depending on if the symbol is
20# found somewhere in the source,
21# - "platforms" is empty if it exists on all platforms, otherwise it contains
22# comma-separated list of the platform, just as they are if the symbol exists
23# for those platforms, or prepended with a "!" if not. This helps resolve
62dc5aad 24# symbol name variants for platforms where the names are too long for the
948d0125 25# compiler or linker, or if the systems is case insensitive and there is a
62dc5aad
RL
26# clash, or the symbol is implemented differently (see
27# EXPORT_VAR_AS_FUNCTION). This script assumes renaming of symbols is found
28# in the file crypto/symhacks.h.
29# The semantics for the platforms is that every item is checked against the
5012158a
LJ
30# environment. For the negative items ("!FOO"), if any of them is false
31# (i.e. "FOO" is true) in the environment, the corresponding symbol can't be
62dc5aad
RL
32# used. For the positive itms, if all of them are false in the environment,
33# the corresponding symbol can't be used. Any combination of positive and
34# negative items are possible, and of course leave room for some redundancy.
948d0125
RL
35# - "kind" is "FUNCTION" or "VARIABLE". The meaning of that is obvious.
36# - "algorithms" is a comma-separated list of algorithm names. This helps
37# exclude symbols that are part of an algorithm that some user wants to
38# exclude.
39#
d02b48c6 40
3fa04f0d
RL
41use lib ".";
42use configdata;
d7465918 43use File::Spec::Functions;
3fa04f0d 44
d399fdf8
RL
45my $debug=0;
46
d7465918
RL
47my $crypto_num= catfile($config{sourcedir},"util","libeay.num");
48my $ssl_num= catfile($config{sourcedir},"util","ssleay.num");
cd4c36ad 49my $libname;
d02b48c6 50
47339f61 51my $do_update = 0;
1449bda0 52my $do_rewrite = 1;
47339f61
DSH
53my $do_crypto = 0;
54my $do_ssl = 0;
0f583f69 55my $do_ctest = 0;
967f4ca8 56my $do_ctestall = 0;
c47c6196 57my $do_checkexist = 0;
47339f61 58
62dc5aad 59my $VMSVAX=0;
af55c09d 60my $VMSNonVAX=0;
948d0125
RL
61my $VMS=0;
62my $W32=0;
0f583f69 63my $NT=0;
cd4c36ad 64my $OS2=0;
e863d920 65my $linux=0;
28a98809 66# Set this to make typesafe STACK definitions appear in DEF
e41c8d6a 67my $safe_stack_def = 0;
31ff97b2 68
e03b2987 69my @known_platforms = ( "__FreeBSD__", "PERL5",
700b4a4a
RS
70 "EXPORT_VAR_AS_FUNCTION", "ZLIB"
71 );
6d23cf97 72my @known_ossl_platforms = ( "VMS", "WIN32", "WINNT", "OS2" );
948d0125 73my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
3f07fe09 74 "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
1f7103b6 75 "SHA256", "SHA512", "RMD160",
d2ad1c96 76 "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "EC2M",
96afc1cf 77 "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
48f14845 78 "SCRYPT", "CHACHA", "POLY1305",
e0d6132b
BM
79 # EC_NISTP_64_GCC_128
80 "EC_NISTP_64_GCC_128",
3f07fe09
RL
81 # Envelope "algorithms"
82 "EVP", "X509", "ASN1_TYPEDEFS",
83 # Helper "algorithms"
84 "BIO", "COMP", "BUFFER", "LHASH", "STACK", "ERR",
85 "LOCKING",
86 # External "algorithms"
e36827f6 87 "FP_API", "STDIO", "SOCK", "DGRAM",
6ac11bd0 88 "CRYPTO_MDEBUG",
6cb68620 89 # Engines
05d7bf6c 90 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
0423f812
BK
91 # Entropy Gathering
92 "EGD",
0cea8832
RP
93 # Certificate Transparency
94 "CT",
47bbaa5b
DW
95 # RFC3779
96 "RFC3779",
c20276e4 97 # TLS
e481f9b9 98 "PSK", "SRP", "HEARTBEATS",
8931b30d
DSH
99 # CMS
100 "CMS",
d8bd55a3
DSH
101 # CryptoAPI Engine
102 "CAPIENG",
3881d810
DSH
103 # SSL v3 method
104 "SSL3_METHOD",
36246be9
DSH
105 # NEXTPROTONEG
106 "NEXTPROTONEG",
4ccfe5f4 107 # Deprecated functions
7a556fb6
DSH
108 "DEPRECATEDIN_0_9_8",
109 "DEPRECATEDIN_1_0_0",
110 "DEPRECATEDIN_1_1_0",
9ef562bc 111 # SCTP
3dd814ac
MC
112 "SCTP",
113 # SRTP
114 "SRTP",
8fdb4f1a 115 # SSL TRACE
e0fc7961
DSH
116 "SSL_TRACE",
117 # Unit testing
dc0e9a35
MC
118 "UNIT_TEST",
119 # OCB mode
1a53f1d6
RS
120 "OCB",
121 # APPLINK (win build feature?)
122 "APPLINK"
123 );
948d0125 124
2854c798
DSH
125my %disabled_algorithms;
126
127foreach (@known_algorithms) {
128 $disabled_algorithms{$_} = 0;
129}
3af45d99 130# disabled by default
3af45d99 131$disabled_algorithms{"STATIC_ENGINE"} = 1;
2854c798 132
8931b30d 133my $zlib;
987bebaf 134
3fa04f0d 135foreach (@ARGV, split(/ /, $config{options}))
d02b48c6 136 {
62dc5aad 137 $debug=1 if $_ eq "debug";
06c68491 138 $W32=1 if $_ eq "32";
6d23cf97 139 die "win16 not supported" if $_ eq "16";
06c68491
DSH
140 if($_ eq "NT") {
141 $W32 = 1;
142 $NT = 1;
143 }
62dc5aad
RL
144 if ($_ eq "VMS-VAX") {
145 $VMS=1;
146 $VMSVAX=1;
147 }
af55c09d 148 if ($_ eq "VMS-NonVAX") {
62dc5aad 149 $VMS=1;
af55c09d 150 $VMSNonVAX=1;
62dc5aad 151 }
e863d920
MC
152 if ($_ eq "linux") {
153 $linux=1;
154 }
a388633d 155 $VMS=$VMSNonVAX=1 if $_ eq "VMS";
cd4c36ad 156 $OS2=1 if $_ eq "OS2";
b2cf7c64 157 if ($_ eq "zlib" || $_ eq "enable-zlib" || $_ eq "zlib-dynamic"
8931b30d
DSH
158 || $_ eq "enable-zlib-dynamic") {
159 $zlib = 1;
160 }
161
d02b48c6 162 $do_ssl=1 if $_ eq "ssleay";
cd4c36ad
RL
163 if ($_ eq "ssl") {
164 $do_ssl=1;
165 $libname=$_
166 }
d02b48c6 167 $do_crypto=1 if $_ eq "libeay";
cd4c36ad
RL
168 if ($_ eq "crypto") {
169 $do_crypto=1;
170 $libname=$_;
171 }
55a9cc6e 172 $do_update=1 if $_ eq "update";
948d0125 173 $do_rewrite=1 if $_ eq "rewrite";
12aefe78 174 $do_ctest=1 if $_ eq "ctest";
967f4ca8 175 $do_ctestall=1 if $_ eq "ctestall";
c47c6196 176 $do_checkexist=1 if $_ eq "exist";
7a556fb6
DSH
177 if (/^--api=(\d+)\.(\d+)\.(\d+)$/) {
178 my $apiv = sprintf "%x%02x%02x", $1, $2, $3;
179 foreach (keys %disabled_algorithms) {
180 if (/^DEPRECATEDIN_(\d+)_(\d+)_(\d+)$/) {
181 my $depv = sprintf "%x%02x%02x", $1, $2, $3;
182 $disabled_algorithms{$_} = 1 if $apiv ge $depv;
183 }
184 }
185 }
186 if (/^no-deprecated$/) {
187 foreach (keys %disabled_algorithms) {
188 if (/^DEPRECATEDIN_/) {
189 $disabled_algorithms{$_} = 1;
190 }
191 }
192 }
193 elsif (/^(enable|disable|no)-(.*)$/) {
2854c798
DSH
194 my $alg = uc $2;
195 $alg =~ tr/-/_/;
196 if (exists $disabled_algorithms{$alg}) {
197 $disabled_algorithms{$alg} = $1 eq "enable" ? 0 : 1;
198 }
d02b48c6
RE
199 }
200
2854c798 201 }
12aefe78 202
cd4c36ad
RL
203if (!$libname) {
204 if ($do_ssl) {
205 $libname="SSLEAY";
206 }
207 if ($do_crypto) {
208 $libname="LIBEAY";
209 }
210}
211
948d0125 212# If no platform is given, assume WIN32
e863d920 213if ($W32 + $VMS + $OS2 + $linux == 0) {
948d0125
RL
214 $W32 = 1;
215}
a388633d
RL
216die "Please, only one platform at a time"
217 if ($W32 + $VMS + $OS2 + $linux > 1);
948d0125 218
d02b48c6
RE
219if (!$do_ssl && !$do_crypto)
220 {
a388633d 221 print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT | OS2 | linux | VMS ]\n";
d02b48c6
RE
222 exit(1);
223 }
224
225%ssl_list=&load_numbers($ssl_num);
55a9cc6e 226$max_ssl = $max_num;
d02b48c6 227%crypto_list=&load_numbers($crypto_num);
55a9cc6e 228$max_crypto = $max_num;
d02b48c6 229
dee502be 230my $ssl="include/openssl/ssl.h";
dee502be
RL
231$ssl.=" include/openssl/tls1.h";
232$ssl.=" include/openssl/srtp.h";
d02b48c6 233
65b1ff4a
RL
234# We use headers found in include/openssl and include/internal only.
235# The latter is needed so libssl.so/.dll/.exe can link properly.
dee502be 236my $crypto ="include/openssl/crypto.h";
68570797
RL
237$crypto.=" include/internal/o_dir.h";
238$crypto.=" include/internal/o_str.h";
71a04cfc 239$crypto.=" include/internal/threads.h";
dee502be
RL
240$crypto.=" include/openssl/des.h" ; # unless $no_des;
241$crypto.=" include/openssl/idea.h" ; # unless $no_idea;
242$crypto.=" include/openssl/rc4.h" ; # unless $no_rc4;
243$crypto.=" include/openssl/rc5.h" ; # unless $no_rc5;
244$crypto.=" include/openssl/rc2.h" ; # unless $no_rc2;
245$crypto.=" include/openssl/blowfish.h" ; # unless $no_bf;
246$crypto.=" include/openssl/cast.h" ; # unless $no_cast;
247$crypto.=" include/openssl/whrlpool.h" ;
248$crypto.=" include/openssl/md2.h" ; # unless $no_md2;
249$crypto.=" include/openssl/md4.h" ; # unless $no_md4;
250$crypto.=" include/openssl/md5.h" ; # unless $no_md5;
251$crypto.=" include/openssl/mdc2.h" ; # unless $no_mdc2;
252$crypto.=" include/openssl/sha.h" ; # unless $no_sha;
253$crypto.=" include/openssl/ripemd.h" ; # unless $no_ripemd;
254$crypto.=" include/openssl/aes.h" ; # unless $no_aes;
255$crypto.=" include/openssl/camellia.h" ; # unless $no_camellia;
256$crypto.=" include/openssl/seed.h"; # unless $no_seed;
d02b48c6 257
dee502be
RL
258$crypto.=" include/openssl/bn.h";
259$crypto.=" include/openssl/rsa.h" ; # unless $no_rsa;
260$crypto.=" include/openssl/dsa.h" ; # unless $no_dsa;
261$crypto.=" include/openssl/dh.h" ; # unless $no_dh;
262$crypto.=" include/openssl/ec.h" ; # unless $no_ec;
dee502be
RL
263$crypto.=" include/openssl/hmac.h" ; # unless $no_hmac;
264$crypto.=" include/openssl/cmac.h" ;
d02b48c6 265
dee502be
RL
266$crypto.=" include/openssl/engine.h"; # unless $no_engine;
267$crypto.=" include/openssl/stack.h" ; # unless $no_stack;
268$crypto.=" include/openssl/buffer.h" ; # unless $no_buffer;
269$crypto.=" include/openssl/bio.h" ; # unless $no_bio;
270$crypto.=" include/openssl/dso.h" ; # unless $no_dso;
271$crypto.=" include/openssl/lhash.h" ; # unless $no_lhash;
272$crypto.=" include/openssl/conf.h";
273$crypto.=" include/openssl/txt_db.h";
d02b48c6 274
dee502be
RL
275$crypto.=" include/openssl/evp.h" ; # unless $no_evp;
276$crypto.=" include/openssl/objects.h";
277$crypto.=" include/openssl/pem.h";
278#$crypto.=" include/openssl/meth.h";
279$crypto.=" include/openssl/asn1.h";
280$crypto.=" include/openssl/asn1t.h";
dee502be
RL
281$crypto.=" include/openssl/err.h" ; # unless $no_err;
282$crypto.=" include/openssl/pkcs7.h";
283$crypto.=" include/openssl/pkcs12.h";
284$crypto.=" include/openssl/x509.h";
285$crypto.=" include/openssl/x509_vfy.h";
286$crypto.=" include/openssl/x509v3.h";
287$crypto.=" include/openssl/ts.h";
288$crypto.=" include/openssl/rand.h";
289$crypto.=" include/openssl/comp.h" ; # unless $no_comp;
290$crypto.=" include/openssl/ocsp.h";
291$crypto.=" include/openssl/ui.h";
dee502be 292#$crypto.=" include/openssl/store.h";
dee502be 293$crypto.=" include/openssl/cms.h";
dee502be
RL
294$crypto.=" include/openssl/srp.h";
295$crypto.=" include/openssl/modes.h";
38148a23 296$crypto.=" include/openssl/async.h";
0cea8832 297$crypto.=" include/openssl/ct.h";
d02b48c6 298
dee502be 299my $symhacks="include/openssl/symhacks.h";
55a9cc6e 300
948d0125
RL
301my @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks);
302my @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks);
47339f61 303
55a9cc6e
DSH
304if ($do_update) {
305
306if ($do_ssl == 1) {
948d0125
RL
307
308 &maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols);
309 if ($do_rewrite == 1) {
310 open(OUT, ">$ssl_num");
311 &rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols);
948d0125
RL
312 } else {
313 open(OUT, ">>$ssl_num");
314 }
315 &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols);
55a9cc6e
DSH
316 close OUT;
317}
318
319if($do_crypto == 1) {
948d0125
RL
320
321 &maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols);
322 if ($do_rewrite == 1) {
323 open(OUT, ">$crypto_num");
324 &rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols);
325 } else {
326 open(OUT, ">>$crypto_num");
327 }
328 &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols);
55a9cc6e 329 close OUT;
12aefe78
DSH
330}
331
c47c6196
DSH
332} elsif ($do_checkexist) {
333 &check_existing(*ssl_list, @ssl_symbols)
334 if $do_ssl == 1;
335 &check_existing(*crypto_list, @crypto_symbols)
336 if $do_crypto == 1;
967f4ca8 337} elsif ($do_ctest || $do_ctestall) {
12aefe78
DSH
338
339 print <<"EOF";
340
341/* Test file to check all DEF file symbols are present by trying
342 * to link to all of them. This is *not* intended to be run!
343 */
344
345int main()
346{
347EOF
948d0125 348 &print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols)
12aefe78
DSH
349 if $do_ssl == 1;
350
948d0125 351 &print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols)
12aefe78
DSH
352 if $do_crypto == 1;
353
354 print "}\n";
55a9cc6e
DSH
355
356} else {
8cf65228 357
cd4c36ad 358 &print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
55a9cc6e
DSH
359 if $do_ssl == 1;
360
cd4c36ad 361 &print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
55a9cc6e 362 if $do_crypto == 1;
8cf65228 363
55a9cc6e 364}
d02b48c6 365
d02b48c6
RE
366
367sub do_defs
47339f61 368{
948d0125 369 my($name,$files,$symhacksfile)=@_;
0f583f69 370 my $file;
47339f61 371 my @ret;
948d0125
RL
372 my %syms;
373 my %platform; # For anything undefined, we assume ""
374 my %kind; # For anything undefined, we assume "FUNCTION"
375 my %algorithm; # For anything undefined, we assume ""
62dc5aad
RL
376 my %variant;
377 my %variant_cnt; # To be able to allocate "name{n}" if "name"
378 # is the same name as the original.
0f583f69 379 my $cpp;
3f07fe09 380 my %unknown_algorithms = ();
07c4c14c 381 my $parens = 0;
d02b48c6 382
948d0125 383 foreach $file (split(/\s+/,$symhacksfile." ".$files))
d02b48c6 384 {
d7465918
RL
385 my $fn = catfile($config{sourcedir},$file);
386 print STDERR "DEBUG: starting on $fn:\n" if $debug;
387 open(IN,"<$fn") || die "unable to open $fn:$!\n";
0f583f69 388 my $line = "", my $def= "";
47339f61 389 my %tag = (
d399fdf8
RL
390 (map { $_ => 0 } @known_platforms),
391 (map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
cf1b7d96 392 (map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
07c4c14c 393 (map { "OPENSSL_USE_".$_ => 0 } @known_algorithms),
47339f61 394 NOPROTO => 0,
47339f61
DSH
395 PERL5 => 0,
396 _WINDLL => 0,
47339f61
DSH
397 CONST_STRICT => 0,
398 TRUE => 1,
399 );
948d0125 400 my $symhacking = $file eq $symhacksfile;
267a1927
RL
401 my @current_platforms = ();
402 my @current_algorithms = ();
403
62dc5aad
RL
404 # params: symbol, alias, platforms, kind
405 # The reason to put this subroutine in a variable is that
406 # it will otherwise create it's own, unshared, version of
407 # %tag and %variant...
408 my $make_variant = sub
409 {
410 my ($s, $a, $p, $k) = @_;
411 my ($a1, $a2);
412
413 print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
414 if (defined($p))
415 {
416 $a1 = join(",",$p,
417 grep(!/^$/,
418 map { $tag{$_} == 1 ? $_ : "" }
419 @known_platforms));
420 }
421 else
422 {
423 $a1 = join(",",
424 grep(!/^$/,
425 map { $tag{$_} == 1 ? $_ : "" }
426 @known_platforms));
427 }
428 $a2 = join(",",
429 grep(!/^$/,
430 map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
431 @known_ossl_platforms));
432 print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
433 if ($a1 eq "") { $a1 = $a2; }
434 elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
435 if ($a eq $s)
436 {
437 if (!defined($variant_cnt{$s}))
438 {
439 $variant_cnt{$s} = 0;
440 }
441 $variant_cnt{$s}++;
442 $a .= "{$variant_cnt{$s}}";
443 }
c454dbcd
RL
444 my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
445 my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
446 if (!grep(/^$togrep$/,
447 split(/;/, defined($variant{$s})?$variant{$s}:""))) {
448 if (defined($variant{$s})) { $variant{$s} .= ";"; }
449 $variant{$s} .= $toadd;
450 }
62dc5aad
RL
451 print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
452 };
453
454 print STDERR "DEBUG: parsing ----------\n" if $debug;
47339f61 455 while(<IN>) {
07c4c14c 456 if($parens > 0) {
7a556fb6 457 #Inside a DEPRECATEDIN
fa327faf 458 $stored_multiline .= $_;
9ba96fbb 459 $stored_multiline =~ s|\R$||; # Better chomp
7a556fb6 460 print STDERR "DEBUG: Continuing multiline DEPRECATEDIN: $stored_multiline\n" if $debug;
fa327faf
RL
461 $parens = count_parens($stored_multiline);
462 if ($parens == 0) {
7a556fb6
DSH
463 $def .= do_deprecated($stored_multiline,
464 \@current_platforms,
465 \@current_algorithms);
fa327faf 466 }
07c4c14c
MC
467 next;
468 }
40e950ae
DSH
469 if (/\/\* Error codes for the \w+ functions\. \*\//)
470 {
471 undef @tag;
472 last;
473 }
47339f61
DSH
474 if ($line ne '') {
475 $_ = $line . $_;
476 $line = '';
d02b48c6 477 }
47339f61
DSH
478
479 if (/\\$/) {
9ba96fbb 480 $line = $`; # keep what was before the backslash
47339f61
DSH
481 next;
482 }
483
68e57536
AP
484 if(/\/\*/) {
485 if (not /\*\//) { # multiline comment...
486 $line = $_; # ... just accumulate
487 next;
488 } else {
489 s/\/\*.*?\*\///gs;# wipe it
490 }
491 }
492
47339f61 493 if ($cpp) {
68e57536
AP
494 $cpp++ if /^#\s*if/;
495 $cpp-- if /^#\s*endif/;
47339f61 496 next;
9ba96fbb 497 }
d9706f19
MC
498 if (/^#.*ifdef.*cplusplus/) {
499 $cpp = 1;
500 next;
501 }
47339f61 502
47339f61 503 s/{[^{}]*}//gs; # ignore {} blocks
6cb68620 504 print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
d399fdf8 505 print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
3f07fe09 506 if (/^\#\s*ifndef\s+(.*)/) {
d399fdf8 507 push(@tag,"-");
d02b48c6
RE
508 push(@tag,$1);
509 $tag{$1}=-1;
d399fdf8 510 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
3f07fe09 511 } elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
d399fdf8
RL
512 push(@tag,"-");
513 if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
514 my $tmp_1 = $1;
515 my $tmp_;
516 foreach $tmp_ (split '\&\&',$tmp_1) {
517 $tmp_ =~ /!defined\(([^\)]+)\)/;
518 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
519 push(@tag,$1);
520 $tag{$1}=-1;
521 }
522 } else {
523 print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
524 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
525 push(@tag,$1);
526 $tag{$1}=-1;
527 }
8aa36bca 528 } elsif (/^\#\s*ifdef\s+(\S*)/) {
d399fdf8 529 push(@tag,"-");
d02b48c6
RE
530 push(@tag,$1);
531 $tag{$1}=1;
d399fdf8 532 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
3f07fe09 533 } elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
d399fdf8
RL
534 push(@tag,"-");
535 if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
536 my $tmp_1 = $1;
537 my $tmp_;
538 foreach $tmp_ (split '\|\|',$tmp_1) {
539 $tmp_ =~ /defined\(([^\)]+)\)/;
540 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
541 push(@tag,$1);
542 $tag{$1}=1;
543 }
544 } else {
545 print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
546 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
547 push(@tag,$1);
548 $tag{$1}=1;
549 }
948d0125 550 } elsif (/^\#\s*error\s+(\w+) is disabled\./) {
d399fdf8
RL
551 my $tag_i = $#tag;
552 while($tag[$tag_i] ne "-") {
553 if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
554 $tag{$tag[$tag_i]}=2;
555 print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
556 }
557 $tag_i--;
948d0125 558 }
47339f61 559 } elsif (/^\#\s*endif/) {
d399fdf8 560 my $tag_i = $#tag;
665560e9 561 while($tag_i > 0 && $tag[$tag_i] ne "-") {
d399fdf8
RL
562 my $t=$tag[$tag_i];
563 print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
564 if ($tag{$t}==2) {
565 $tag{$t}=-1;
566 } else {
567 $tag{$t}=0;
568 }
569 print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
570 pop(@tag);
571 if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
572 $t=$1;
07c4c14c
MC
573 } elsif($t =~ /^OPENSSL_USE_([A-Z0-9_]+)$/) {
574 $t=$1;
d399fdf8
RL
575 } else {
576 $t="";
577 }
578 if ($t ne ""
579 && !grep(/^$t$/, @known_algorithms)) {
580 $unknown_algorithms{$t} = 1;
581 #print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
582 }
583 $tag_i--;
948d0125 584 }
d02b48c6 585 pop(@tag);
47339f61 586 } elsif (/^\#\s*else/) {
d399fdf8 587 my $tag_i = $#tag;
d9706f19 588 die "$file unmatched else\n" if $tag_i < 0;
d399fdf8
RL
589 while($tag[$tag_i] ne "-") {
590 my $t=$tag[$tag_i];
591 $tag{$t}= -$tag{$t};
592 print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
593 $tag_i--;
594 }
47339f61 595 } elsif (/^\#\s*if\s+1/) {
d399fdf8 596 push(@tag,"-");
47339f61
DSH
597 # Dummy tag
598 push(@tag,"TRUE");
599 $tag{"TRUE"}=1;
d399fdf8 600 print STDERR "DEBUG: $file: found 1\n" if $debug;
1e414935 601 } elsif (/^\#\s*if\s+0/) {
d399fdf8 602 push(@tag,"-");
1e414935
BM
603 # Dummy tag
604 push(@tag,"TRUE");
605 $tag{"TRUE"}=-1;
d399fdf8 606 print STDERR "DEBUG: $file: found 0\n" if $debug;
d9706f19
MC
607 } elsif (/^\#\s*if\s+/) {
608 #Some other unrecognized "if" style
609 push(@tag,"-");
948d0125 610 } elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
2ae87d46 611 && $symhacking && $tag{'TRUE'} != -1) {
62dc5aad
RL
612 # This is for aliasing. When we find an alias,
613 # we have to invert
614 &$make_variant($1,$2);
615 print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
948d0125
RL
616 }
617 if (/^\#/) {
267a1927
RL
618 @current_platforms =
619 grep(!/^$/,
d399fdf8
RL
620 map { $tag{$_} == 1 ? $_ :
621 $tag{$_} == -1 ? "!".$_ : "" }
267a1927 622 @known_platforms);
d399fdf8
RL
623 push @current_platforms
624 , grep(!/^$/,
625 map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
626 $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_ : "" }
627 @known_ossl_platforms);
07c4c14c 628 @current_algorithms = ();
267a1927
RL
629 @current_algorithms =
630 grep(!/^$/,
cf1b7d96 631 map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
267a1927 632 @known_algorithms);
07c4c14c
MC
633 push @current_algorithms
634 , grep(!/^$/,
635 map { $tag{"OPENSSL_USE_".$_} == 1 ? $_ : "" }
636 @known_algorithms);
267a1927
RL
637 $def .=
638 "#INFO:"
639 .join(',',@current_platforms).":"
640 .join(',',@current_algorithms).";";
47339f61
DSH
641 next;
642 }
2ae87d46
RL
643 if ($tag{'TRUE'} != -1) {
644 if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
645 next;
646 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
647 $def .= "int d2i_$3(void);";
648 $def .= "int i2d_$3(void);";
62dc5aad
RL
649 # Variant for platforms that do not
650 # have to access globale variables
651 # in shared libraries through functions
652 $def .=
653 "#INFO:"
654 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
655 .join(',',@current_algorithms).";";
2ae87d46 656 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
657 $def .=
658 "#INFO:"
659 .join(',',@current_platforms).":"
660 .join(',',@current_algorithms).";";
661 # Variant for platforms that have to
662 # access globale variables in shared
663 # libraries through functions
664 &$make_variant("$2_it","$2_it",
665 "EXPORT_VAR_AS_FUNCTION",
666 "FUNCTION");
2ae87d46
RL
667 next;
668 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
669 $def .= "int d2i_$3(void);";
670 $def .= "int i2d_$3(void);";
671 $def .= "int $3_free(void);";
672 $def .= "int $3_new(void);";
62dc5aad
RL
673 # Variant for platforms that do not
674 # have to access globale variables
675 # in shared libraries through functions
676 $def .=
677 "#INFO:"
678 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
679 .join(',',@current_algorithms).";";
2ae87d46 680 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
681 $def .=
682 "#INFO:"
683 .join(',',@current_platforms).":"
684 .join(',',@current_algorithms).";";
685 # Variant for platforms that have to
686 # access globale variables in shared
687 # libraries through functions
688 &$make_variant("$2_it","$2_it",
689 "EXPORT_VAR_AS_FUNCTION",
690 "FUNCTION");
691 next;
2ae87d46
RL
692 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
693 /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
694 $def .= "int d2i_$1(void);";
695 $def .= "int i2d_$1(void);";
696 $def .= "int $1_free(void);";
697 $def .= "int $1_new(void);";
62dc5aad
RL
698 # Variant for platforms that do not
699 # have to access globale variables
700 # in shared libraries through functions
701 $def .=
702 "#INFO:"
703 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
704 .join(',',@current_algorithms).";";
2ae87d46 705 $def .= "OPENSSL_EXTERN int $1_it;";
62dc5aad
RL
706 $def .=
707 "#INFO:"
708 .join(',',@current_platforms).":"
709 .join(',',@current_algorithms).";";
710 # Variant for platforms that have to
711 # access globale variables in shared
712 # libraries through functions
713 &$make_variant("$1_it","$1_it",
714 "EXPORT_VAR_AS_FUNCTION",
715 "FUNCTION");
2ae87d46
RL
716 next;
717 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
718 $def .= "int d2i_$2(void);";
719 $def .= "int i2d_$2(void);";
62dc5aad
RL
720 # Variant for platforms that do not
721 # have to access globale variables
722 # in shared libraries through functions
723 $def .=
724 "#INFO:"
725 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
726 .join(',',@current_algorithms).";";
2ae87d46 727 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
728 $def .=
729 "#INFO:"
730 .join(',',@current_platforms).":"
731 .join(',',@current_algorithms).";";
732 # Variant for platforms that have to
733 # access globale variables in shared
734 # libraries through functions
735 &$make_variant("$2_it","$2_it",
736 "EXPORT_VAR_AS_FUNCTION",
737 "FUNCTION");
2ae87d46 738 next;
ea3675b5
DSH
739 } elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
740 $def .= "int $1_free(void);";
741 $def .= "int $1_new(void);";
742 next;
2ae87d46
RL
743 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
744 $def .= "int d2i_$2(void);";
745 $def .= "int i2d_$2(void);";
746 $def .= "int $2_free(void);";
747 $def .= "int $2_new(void);";
62dc5aad
RL
748 # Variant for platforms that do not
749 # have to access globale variables
750 # in shared libraries through functions
751 $def .=
752 "#INFO:"
753 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
754 .join(',',@current_algorithms).";";
2ae87d46 755 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
756 $def .=
757 "#INFO:"
758 .join(',',@current_platforms).":"
759 .join(',',@current_algorithms).";";
760 # Variant for platforms that have to
761 # access globale variables in shared
762 # libraries through functions
763 &$make_variant("$2_it","$2_it",
764 "EXPORT_VAR_AS_FUNCTION",
765 "FUNCTION");
2ae87d46 766 next;
62dc5aad
RL
767 } elsif (/^\s*DECLARE_ASN1_ITEM\s*\(\s*(\w*)\s*\)/) {
768 # Variant for platforms that do not
769 # have to access globale variables
770 # in shared libraries through functions
771 $def .=
772 "#INFO:"
773 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
774 .join(',',@current_algorithms).";";
2ae87d46 775 $def .= "OPENSSL_EXTERN int $1_it;";
62dc5aad
RL
776 $def .=
777 "#INFO:"
778 .join(',',@current_platforms).":"
779 .join(',',@current_algorithms).";";
780 # Variant for platforms that have to
781 # access globale variables in shared
782 # libraries through functions
783 &$make_variant("$1_it","$1_it",
784 "EXPORT_VAR_AS_FUNCTION",
785 "FUNCTION");
2ae87d46 786 next;
f86abc2e 787 } elsif (/^\s*DECLARE_ASN1_NDEF_FUNCTION\s*\(\s*(\w*)\s*\)/) {
97ebe047 788 $def .= "int i2d_$1_NDEF(void);";
2ae87d46
RL
789 } elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
790 next;
16094305
DSH
791 } elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION\s*\(\s*(\w*)\s*\)/) {
792 $def .= "int $1_print_ctx(void);";
793 next;
794 } elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
795 $def .= "int $2_print_ctx(void);";
796 next;
62dc5aad
RL
797 } elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) {
798 next;
2ae87d46 799 } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
47738cba
AP
800 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ||
801 /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
802 $def .=
803 "#INFO:"
6d23cf97 804 .join(',',@current_platforms).":"
2ae87d46
RL
805 .join(',',@current_algorithms).";";
806 $def .= "int PEM_read_$1(void);";
807 $def .= "int PEM_write_$1(void);";
808 $def .=
809 "#INFO:"
810 .join(',',@current_platforms).":"
811 .join(',',@current_algorithms).";";
812 # Things that are everywhere
813 $def .= "int PEM_read_bio_$1(void);";
814 $def .= "int PEM_write_bio_$1(void);";
815 next;
816 } elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
e43bfb29 817 /^DECLARE_PEM_write_const\s*\(\s*(\w*)\s*,/ ||
2ae87d46 818 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
819 $def .=
820 "#INFO:"
6d23cf97 821 .join(',',@current_platforms).":"
2ae87d46
RL
822 .join(',',@current_algorithms).";";
823 $def .= "int PEM_write_$1(void);";
824 $def .=
825 "#INFO:"
826 .join(',',@current_platforms).":"
827 .join(',',@current_algorithms).";";
828 # Things that are everywhere
829 $def .= "int PEM_write_bio_$1(void);";
830 next;
831 } elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
832 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
833 $def .=
834 "#INFO:"
6d23cf97 835 .join(',',@current_platforms).":"
2ae87d46
RL
836 .join(',',@current_algorithms).";";
837 $def .= "int PEM_read_$1(void);";
838 $def .=
839 "#INFO:"
840 .join(',',@current_platforms).":"
841 .join(',',@current_algorithms).";";
842 # Things that are everywhere
843 $def .= "int PEM_read_bio_$1(void);";
844 next;
62dc5aad
RL
845 } elsif (/^OPENSSL_DECLARE_GLOBAL\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
846 # Variant for platforms that do not
847 # have to access globale variables
848 # in shared libraries through functions
849 $def .=
850 "#INFO:"
851 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
852 .join(',',@current_algorithms).";";
853 $def .= "OPENSSL_EXTERN int _shadow_$2;";
854 $def .=
855 "#INFO:"
856 .join(',',@current_platforms).":"
857 .join(',',@current_algorithms).";";
858 # Variant for platforms that have to
859 # access globale variables in shared
860 # libraries through functions
861 &$make_variant("_shadow_$2","_shadow_$2",
862 "EXPORT_VAR_AS_FUNCTION",
863 "FUNCTION");
7a556fb6 864 } elsif (/^\s*DEPRECATEDIN/) {
07c4c14c 865 $parens = count_parens($_);
fa327faf 866 if ($parens == 0) {
7a556fb6
DSH
867 $def .= do_deprecated($_,
868 \@current_platforms,
869 \@current_algorithms);
fa327faf
RL
870 } else {
871 $stored_multiline = $_;
9ba96fbb 872 $stored_multiline =~ s|\R$||;
7a556fb6 873 print STDERR "DEBUG: Found multiline DEPRECATEDIN starting with: $stored_multiline\n" if $debug;
fa327faf
RL
874 next;
875 }
2ae87d46 876 } elsif ($tag{'CONST_STRICT'} != 1) {
948d0125 877 if (/\{|\/\*|\([^\)]*$/) {
47339f61
DSH
878 $line = $_;
879 } else {
880 $def .= $_;
881 }
d02b48c6
RE
882 }
883 }
2ae87d46 884 }
d02b48c6 885 close(IN);
d9706f19 886 die "$file: Unmatched tags\n" if $#tag >= 0;
47339f61 887
948d0125
RL
888 my $algs;
889 my $plays;
890
62dc5aad 891 print STDERR "DEBUG: postprocessing ----------\n" if $debug;
47339f61 892 foreach (split /;/, $def) {
948d0125 893 my $s; my $k = "FUNCTION"; my $p; my $a;
47339f61
DSH
894 s/^[\n\s]*//g;
895 s/[\n\s]*$//g;
948d0125 896 next if(/\#undef/);
47339f61 897 next if(/typedef\W/);
948d0125
RL
898 next if(/\#define/);
899
68e57536
AP
900 # Reduce argument lists to empty ()
901 # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
902 while(/\(.*\)/s) {
903 s/\([^\(\)]+\)/\{\}/gs;
904 s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
905 }
906 # pretend as we didn't use curly braces: {} -> ()
907 s/\{\}/\(\)/gs;
908
909 s/STACK_OF\(\)/void/gs;
174c86a2 910 s/LHASH_OF\(\)/void/gs;
68e57536 911
62dc5aad 912 print STDERR "DEBUG: \$_ = \"$_\"\n" if $debug;
948d0125
RL
913 if (/^\#INFO:([^:]*):(.*)$/) {
914 $plats = $1;
915 $algs = $2;
89eeccac 916 print STDERR "DEBUG: found info on platforms ($plats) and algorithms ($algs)\n" if $debug;
948d0125 917 next;
62dc5aad 918 } elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+(\{[0-9]+\})?)(\[[0-9]*\])*\s*$/) {
948d0125
RL
919 $s = $1;
920 $k = "VARIABLE";
89eeccac 921 print STDERR "DEBUG: found external variable $s\n" if $debug;
68e57536 922 } elsif (/TYPEDEF_\w+_OF/s) {
47339f61 923 next;
68e57536
AP
924 } elsif (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
925 $s = $1; # a function name!
89eeccac 926 print STDERR "DEBUG: found function $s\n" if $debug;
47339f61
DSH
927 } elsif (/\(/ and not (/=/)) {
928 print STDERR "File $file: cannot parse: $_;\n";
948d0125
RL
929 next;
930 } else {
931 next;
932 }
933
934 $syms{$s} = 1;
935 $kind{$s} = $k;
936
937 $p = $plats;
938 $a = $algs;
948d0125 939
62dc5aad
RL
940 $platform{$s} =
941 &reduce_platforms((defined($platform{$s})?$platform{$s}.',':"").$p);
948d0125
RL
942 $algorithm{$s} .= ','.$a;
943
62dc5aad 944 if (defined($variant{$s})) {
c454dbcd
RL
945 foreach $v (split /;/,$variant{$s}) {
946 (my $r, my $p, my $k) = split(/:/,$v);
947 my $ip = join ',',map({ /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p);
948 $syms{$r} = 1;
949 if (!defined($k)) { $k = $kind{$s}; }
950 $kind{$r} = $k."(".$s.")";
951 $algorithm{$r} = $algorithm{$s};
952 $platform{$r} = &reduce_platforms($platform{$s}.",".$p.",".$p);
953 $platform{$s} = &reduce_platforms($platform{$s}.','.$ip.','.$ip);
954 print STDERR "DEBUG: \$variant{\"$s\"} = ",$v,"; \$r = $r; \$p = ",$platform{$r},"; \$a = ",$algorithm{$r},"; \$kind = ",$kind{$r},"\n" if $debug;
955 }
47339f61 956 }
62dc5aad 957 print STDERR "DEBUG: \$s = $s; \$p = ",$platform{$s},"; \$a = ",$algorithm{$s},"; \$kind = ",$kind{$s},"\n" if $debug;
d02b48c6 958 }
d02b48c6
RE
959 }
960
948d0125 961 # Prune the returned symbols
47339f61 962
948d0125 963 delete $syms{"bn_dump1"};
6d23cf97 964 $platform{"BIO_s_log"} .= ",!WIN32,!macintosh";
948d0125 965
2ae87d46
RL
966 $platform{"PEM_read_NS_CERT_SEQ"} = "VMS";
967 $platform{"PEM_write_NS_CERT_SEQ"} = "VMS";
968 $platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
969 $platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
af55c09d
RL
970 $platform{"EVP_sha384"} = "!VMSVAX";
971 $platform{"EVP_sha512"} = "!VMSVAX";
972 $platform{"SHA384_Init"} = "!VMSVAX";
973 $platform{"SHA384_Transform"} = "!VMSVAX";
974 $platform{"SHA384_Update"} = "!VMSVAX";
975 $platform{"SHA384_Final"} = "!VMSVAX";
976 $platform{"SHA384"} = "!VMSVAX";
977 $platform{"SHA512_Init"} = "!VMSVAX";
978 $platform{"SHA512_Transform"} = "!VMSVAX";
979 $platform{"SHA512_Update"} = "!VMSVAX";
980 $platform{"SHA512_Final"} = "!VMSVAX";
981 $platform{"SHA512"} = "!VMSVAX";
982
2ae87d46 983
948d0125
RL
984 # Info we know about
985
948d0125
RL
986 push @ret, map { $_."\\".&info_string($_,"EXIST",
987 $platform{$_},
988 $kind{$_},
989 $algorithm{$_}) } keys %syms;
990
3f07fe09
RL
991 if (keys %unknown_algorithms) {
992 print STDERR "WARNING: mkdef.pl doesn't know the following algorithms:\n";
993 print STDERR "\t",join("\n\t",keys %unknown_algorithms),"\n";
994 }
948d0125
RL
995 return(@ret);
996}
997
62dc5aad
RL
998# Param: string of comma-separated platform-specs.
999sub reduce_platforms
1000{
1001 my ($platforms) = @_;
948d0125
RL
1002 my $pl = defined($platforms) ? $platforms : "";
1003 my %p = map { $_ => 0 } split /,/, $pl;
948d0125
RL
1004 my $ret;
1005
62dc5aad
RL
1006 print STDERR "DEBUG: Entered reduce_platforms with \"$platforms\"\n"
1007 if $debug;
948d0125
RL
1008 # We do this, because if there's code like the following, it really
1009 # means the function exists in all cases and should therefore be
1010 # everywhere. By increasing and decreasing, we may attain 0:
1011 #
1012 # ifndef WIN16
1013 # int foo();
1014 # else
1015 # int _fat foo();
1016 # endif
1017 foreach $platform (split /,/, $pl) {
1018 if ($platform =~ /^!(.*)$/) {
1019 $p{$1}--;
1020 } else {
1021 $p{$platform}++;
d02b48c6 1022 }
47339f61 1023 }
948d0125
RL
1024 foreach $platform (keys %p) {
1025 if ($p{$platform} == 0) { delete $p{$platform}; }
d02b48c6
RE
1026 }
1027
948d0125 1028 delete $p{""};
62dc5aad 1029
c454dbcd 1030 $ret = join(',',sort(map { $p{$_} < 0 ? "!".$_ : $_ } keys %p));
62dc5aad
RL
1031 print STDERR "DEBUG: Exiting reduce_platforms with \"$ret\"\n"
1032 if $debug;
1033 return $ret;
1034}
1035
cc373a37
RS
1036sub info_string
1037{
62dc5aad
RL
1038 (my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_;
1039
1040 my %a = defined($algorithms) ?
1041 map { $_ => 1 } split /,/, $algorithms : ();
1042 my $k = defined($kind) ? $kind : "FUNCTION";
1043 my $ret;
1044 my $p = &reduce_platforms($platforms);
1045
948d0125 1046 delete $a{""};
d02b48c6 1047
948d0125 1048 $ret = $exist;
62dc5aad 1049 $ret .= ":".$p;
948d0125 1050 $ret .= ":".$k;
62dc5aad 1051 $ret .= ":".join(',',sort keys %a);
948d0125
RL
1052 return $ret;
1053}
1054
cc373a37
RS
1055sub maybe_add_info
1056{
948d0125
RL
1057 (my $name, *nums, my @symbols) = @_;
1058 my $sym;
1059 my $new_info = 0;
451e60e9 1060 my %syms=();
948d0125 1061
948d0125
RL
1062 foreach $sym (@symbols) {
1063 (my $s, my $i) = split /\\/, $sym;
948d0125 1064 if (defined($nums{$s})) {
62dc5aad 1065 $i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/;
3addf183 1066 (my $n, my $vers, my $dummy) = split /\\/, $nums{$s};
948d0125 1067 if (!defined($dummy) || $i ne $dummy) {
3addf183 1068 $nums{$s} = $n."\\".$vers."\\".$i;
948d0125 1069 $new_info++;
d399fdf8 1070 print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n" if $debug;
948d0125
RL
1071 }
1072 }
62dc5aad 1073 $syms{$s} = 1;
451e60e9
RL
1074 }
1075
1076 my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums;
1077 foreach $sym (@s) {
3addf183 1078 (my $n, my $vers, my $i) = split /\\/, $nums{$sym};
62dc5aad 1079 if (!defined($syms{$sym}) && $i !~ /^NOEXIST:/) {
451e60e9 1080 $new_info++;
62dc5aad 1081 print STDERR "DEBUG: maybe_add_info for $sym: -> undefined\n" if $debug;
451e60e9 1082 }
948d0125
RL
1083 }
1084 if ($new_info) {
cc373a37 1085 print STDERR "$name: $new_info old symbols have updated info\n";
6d50071e
RL
1086 if (!$do_rewrite) {
1087 print STDERR "You should do a rewrite to fix this.\n";
1088 }
948d0125 1089 } else {
948d0125 1090 }
47339f61 1091}
d02b48c6 1092
62dc5aad
RL
1093# Param: string of comma-separated keywords, each possibly prefixed with a "!"
1094sub is_valid
1095{
1096 my ($keywords_txt,$platforms) = @_;
1097 my (@keywords) = split /,/,$keywords_txt;
d3fdc27a 1098 my ($falsesum, $truesum) = (0, 1);
62dc5aad
RL
1099
1100 # Param: one keyword
1101 sub recognise
1102 {
1103 my ($keyword,$platforms) = @_;
1104
1105 if ($platforms) {
1106 # platforms
af55c09d
RL
1107 if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
1108 if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
62dc5aad
RL
1109 if ($keyword eq "VMS" && $VMS) { return 1; }
1110 if ($keyword eq "WIN32" && $W32) { return 1; }
62dc5aad 1111 if ($keyword eq "WINNT" && $NT) { return 1; }
cd4c36ad 1112 if ($keyword eq "OS2" && $OS2) { return 1; }
62dc5aad
RL
1113 # Special platforms:
1114 # EXPORT_VAR_AS_FUNCTION means that global variables
1115 # will be represented as functions. This currently
1116 # only happens on VMS-VAX.
6d23cf97 1117 if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32)) {
62dc5aad
RL
1118 return 1;
1119 }
8931b30d 1120 if ($keyword eq "ZLIB" && $zlib) { return 1; }
62dc5aad
RL
1121 return 0;
1122 } else {
1123 # algorithms
2854c798 1124 if ($disabled_algorithms{$keyword} == 1) { return 0;}
62dc5aad
RL
1125
1126 # Nothing recognise as true
1127 return 1;
1128 }
1129 }
1130
1131 foreach $k (@keywords) {
1132 if ($k =~ /^!(.*)$/) {
1133 $falsesum += &recognise($1,$platforms);
1134 } else {
d3fdc27a 1135 $truesum *= &recognise($k,$platforms);
62dc5aad
RL
1136 }
1137 }
1138 print STDERR "DEBUG: [",$#keywords,",",$#keywords < 0,"] is_valid($keywords_txt) => (\!$falsesum) && $truesum = ",(!$falsesum) && $truesum,"\n" if $debug;
1139 return (!$falsesum) && $truesum;
1140}
1141
12aefe78
DSH
1142sub print_test_file
1143{
62dc5aad 1144 (*OUT,my $name,*nums,my $testall,my @symbols)=@_;
0f583f69 1145 my $n = 1; my @e; my @r;
948d0125
RL
1146 my $sym; my $prev = ""; my $prefSSLeay;
1147
62dc5aad
RL
1148 (@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
1149 (@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:.*/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
948d0125
RL
1150 @symbols=((sort @e),(sort @r));
1151
1152 foreach $sym (@symbols) {
1153 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
62dc5aad
RL
1154 my $v = 0;
1155 $v = 1 if $i=~ /^.*?:.*?:VARIABLE/;
1156 my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1157 my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1158 if (!defined($nums{$s})) {
1159 print STDERR "Warning: $s does not have a number assigned\n"
1160 if(!$do_update);
1161 } elsif (is_valid($p,1) && is_valid($a,0)) {
1162 my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1163 if ($prev eq $s2) {
1164 print OUT "\t/* The following has already appeared previously */\n";
1165 print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1166 }
1167 $prev = $s2; # To warn about duplicates...
1168
3addf183 1169 (my $nn, my $vers, my $ni) = split /\\/, $nums{$s2};
62dc5aad
RL
1170 if ($v) {
1171 print OUT "\textern int $s2; /* type unknown */ /* $nn $ni */\n";
967f4ca8 1172 } else {
62dc5aad 1173 print OUT "\textern int $s2(); /* type unknown */ /* $nn $ni */\n";
967f4ca8 1174 }
12aefe78
DSH
1175 }
1176 }
1177}
1178
cc373a37
RS
1179sub get_version
1180{
3fa04f0d 1181 return $config{version};
0b352c58
RL
1182}
1183
d02b48c6 1184sub print_def_file
47339f61 1185{
948d0125 1186 (*OUT,my $name,*nums,my @symbols)=@_;
62dc5aad 1187 my $n = 1; my @e; my @r; my @v; my $prev="";
cd4c36ad 1188 my $liboptions="";
0b352c58
RL
1189 my $libname = $name;
1190 my $http_vendor = 'www.openssl.org/';
1191 my $version = get_version();
1192 my $what = "OpenSSL: implementation of Secure Socket Layer";
1193 my $description = "$what $version, $name - http://$http_vendor";
e863d920 1194 my $prevsymversion = "", $prevprevsymversion = "";
a388633d
RL
1195 # For VMS
1196 my $prevnum = 0;
fd40db9e 1197 my $symvtextcount = 0;
a388633d
RL
1198
1199 if ($W32)
1200 { $libname.="32"; }
1201 elsif ($OS2)
1202 { # DLL names should not clash on the whole system.
1203 # However, they should not have any particular relationship
1204 # to the name of the static library. Chose descriptive names
1205 # (must be at most 8 chars).
1206 my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
1207 $libname = $translate{$name} || $name;
1208 $liboptions = <<EOO;
0b352c58
RL
1209INITINSTANCE
1210DATA MULTIPLE NONSHARED
1211EOO
a388633d
RL
1212 # Vendor field can't contain colon, drat; so we omit http://
1213 $description = "\@#$http_vendor:$version#\@$what; DLL for library $name. Build for EMX -Zmtd";
1214 }
d02b48c6 1215
a388633d
RL
1216 if ($W32 || $OS2)
1217 {
1218 print OUT <<"EOF";
d02b48c6 1219;
9b3086fe 1220; Definition file for the DLL version of the $name library from OpenSSL
d02b48c6
RE
1221;
1222
0b352c58 1223LIBRARY $libname $liboptions
d02b48c6 1224
d02b48c6
RE
1225EOF
1226
e863d920 1227 print "EXPORTS\n";
a388633d
RL
1228 }
1229 elsif ($VMS)
1230 {
a388633d 1231 print OUT <<"EOF";
855eff54 1232CASE_SENSITIVE=YES
a388633d
RL
1233SYMBOL_VECTOR=(-
1234EOF
fd40db9e 1235 $symvtextcount = 16; # length of "SYMBOL_VECTOR=(-"
a388633d 1236 }
d02b48c6 1237
e863d920 1238 (@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
62dc5aad 1239 (@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
a388633d
RL
1240 if ($VMS) {
1241 # VMS needs to have the symbols on slot number order
1242 @symbols=(map { $_->[1] }
1243 sort { $a->[0] <=> $b->[0] }
1244 map { (my $s, my $i) = $_ =~ /^(.*?)\\(.*)$/;
1245 die "Error: $s doesn't have a number assigned\n"
1246 if !defined($nums{$s});
1247 (my $n, my @rest) = split /\\/, $nums{$s};
1248 [ $n, $_ ] } (@e, @r, @v));
1249 } else {
1250 @symbols=((sort @e),(sort @r), (sort @v));
1251 }
d02b48c6 1252
e863d920
MC
1253 my ($baseversion, $currversion) = get_openssl_version();
1254 my $thisversion;
1255 do {
1256 if (!defined($thisversion)) {
1257 $thisversion = $baseversion;
47339f61 1258 } else {
e863d920
MC
1259 $thisversion = get_next_version($thisversion);
1260 }
1261 foreach $sym (@symbols) {
1262 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1263 my $v = 0;
1264 $v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
1265 if (!defined($nums{$s})) {
1266 die "Error: $s does not have a number assigned\n"
1267 if(!$do_update);
1268 } else {
1269 (my $n, my $symversion, my $dummy) = split /\\/, $nums{$s};
1270 next if $symversion ne $thisversion;
1271 my %pf = ();
1272 my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1273 my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1274 if (is_valid($p,1) && is_valid($a,0)) {
1275 my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1276 if ($prev eq $s2) {
1277 print STDERR "Warning: Symbol '",$s2,
1278 "' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),
1279 ", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1280 }
1281 $prev = $s2; # To warn about duplicates...
1282 if($linux) {
1283 if ($symversion ne $prevsymversion) {
1284 if ($prevsymversion ne "") {
1285 if ($prevprevsymversion ne "") {
1286 print OUT "} OPENSSL_"
1287 ."$prevprevsymversion;\n\n";
1288 } else {
1289 print OUT "};\n\n";
1290 }
1291 }
1292 print OUT "OPENSSL_$symversion {\n global:\n";
1293 $prevprevsymversion = $prevsymversion;
1294 $prevsymversion = $symversion;
1295 }
1296 print OUT " $s2;\n";
a388633d
RL
1297 } elsif ($VMS) {
1298 while(++$prevnum < $n) {
e84193e4
RL
1299 my $symline=" ,SPARE -\n ,SPARE -\n";
1300 if ($symvtextcount + length($symline) - 2 > 1024) {
a388633d 1301 print OUT ")\nSYMBOL_VECTOR=(-\n";
fd40db9e 1302 $symvtextcount = 16; # length of "SYMBOL_VECTOR=(-"
a388633d 1303 }
e84193e4
RL
1304 if ($symvtextcount == 16) {
1305 # Take away first comma
1306 $symline =~ s/,//;
fd40db9e 1307 }
e84193e4
RL
1308 print OUT $symline;
1309 $symvtextcount += length($symline) - 2;
a388633d
RL
1310 }
1311 (my $s_uc = $s) =~ tr/a-z/A-Z/;
d9aad55a
RL
1312 my $symtype=
1313 $v ? "DATA" : "PROCEDURE";
1314 my $symline=
1315 ($s_uc ne $s
e84193e4
RL
1316 ? " ,$s_uc/$s=$symtype -\n ,$s=$symtype -\n"
1317 : " ,$s=$symtype -\n ,SPARE -\n");
1318 if ($symvtextcount + length($symline) - 2 > 1024) {
a388633d 1319 print OUT ")\nSYMBOL_VECTOR=(-\n";
fd40db9e 1320 $symvtextcount = 16; # length of "SYMBOL_VECTOR=(-"
a388633d 1321 }
e84193e4
RL
1322 if ($symvtextcount == 16) {
1323 # Take away first comma
1324 $symline =~ s/,//;
fd40db9e 1325 }
e84193e4
RL
1326 print OUT $symline;
1327 $symvtextcount += length($symline) - 2;
e863d920
MC
1328 } elsif($v && !$OS2) {
1329 printf OUT " %s%-39s @%-8d DATA\n",
1330 ($W32)?"":"_",$s2,$n;
1331 } else {
1332 printf OUT " %s%-39s @%d\n",
1333 ($W32||$OS2)?"":"_",$s2,$n;
1334 }
9c67ab2f 1335 }
965c1775 1336 }
d02b48c6 1337 }
e863d920
MC
1338 } while ($thisversion ne $currversion);
1339 if ($linux) {
1340 if ($prevprevsymversion ne "") {
1341 print OUT " local: *;\n} OPENSSL_$prevprevsymversion;\n\n";
1342 } else {
1343 print OUT " local: *;\n};\n\n";
1344 }
a388633d
RL
1345 } elsif ($VMS) {
1346 print OUT ")\n";
1347 (my $libvmaj, my $libvmin, my $libvedit) =
1348 $currversion =~ /^(\d+)_(\d+)_(\d+)$/;
1349 # The reason to multiply the edit number with 100 is to make space
1350 # for the possibility that we want to encode the patch letters
1351 print OUT "GSMATCH=LEQUAL,",($libvmaj * 100 + $libvmin),",",($libvedit * 100),"\n";
1352 }
47339f61
DSH
1353 printf OUT "\n";
1354}
d02b48c6
RE
1355
1356sub load_numbers
47339f61
DSH
1357{
1358 my($name)=@_;
1359 my(@a,%ret);
e863d920 1360 my $prevversion;
d02b48c6 1361
55a9cc6e 1362 $max_num = 0;
948d0125
RL
1363 $num_noinfo = 0;
1364 $prev = "";
62dc5aad 1365 $prev_cnt = 0;
55a9cc6e 1366
e863d920
MC
1367 my ($baseversion, $currversion) = get_openssl_version();
1368
d02b48c6 1369 open(IN,"<$name") || die "unable to open $name:$!\n";
47339f61 1370 while (<IN>) {
9ba96fbb 1371 s|\R$||; # Better chomp
d02b48c6
RE
1372 s/#.*$//;
1373 next if /^\s*$/;
1374 @a=split;
948d0125 1375 if (defined $ret{$a[0]}) {
62dc5aad
RL
1376 # This is actually perfectly OK
1377 #print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n";
948d0125
RL
1378 }
1379 if ($max_num > $a[1]) {
1380 print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n";
1381 }
62dc5aad 1382 elsif ($max_num == $a[1]) {
948d0125
RL
1383 # This is actually perfectly OK
1384 #print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n";
62dc5aad
RL
1385 if ($a[0] eq $prev) {
1386 $prev_cnt++;
1387 $a[0] .= "{$prev_cnt}";
1388 }
1389 }
1390 else {
1391 $prev_cnt = 0;
948d0125
RL
1392 }
1393 if ($#a < 2) {
1394 # Existence will be proven later, in do_defs
1395 $ret{$a[0]}=$a[1];
1396 $num_noinfo++;
1397 } else {
e863d920
MC
1398 #Sanity check the version number
1399 if (defined $prevversion) {
1400 check_version_lte($prevversion, $a[2]);
1401 }
1402 check_version_lte($a[2], $currversion);
1403 $prevversion = $a[2];
1404 $ret{$a[0]}=$a[1]."\\".$a[2]."\\".$a[3]; # \\ is a special marker
948d0125 1405 }
55a9cc6e 1406 $max_num = $a[1] if $a[1] > $max_num;
948d0125
RL
1407 $prev=$a[0];
1408 }
1409 if ($num_noinfo) {
1410 print STDERR "Warning: $num_noinfo symbols were without info.";
1411 if ($do_rewrite) {
1412 printf STDERR " The rewrite will fix this.\n";
1413 } else {
1414 printf STDERR " You should do a rewrite to fix this.\n";
1415 }
47339f61 1416 }
d02b48c6
RE
1417 close(IN);
1418 return(%ret);
47339f61 1419}
55a9cc6e 1420
948d0125
RL
1421sub parse_number
1422{
1423 (my $str, my $what) = @_;
3addf183 1424 (my $n, my $v, my $i) = split(/\\/,$str);
948d0125
RL
1425 if ($what eq "n") {
1426 return $n;
1427 } else {
1428 return $i;
1429 }
1430}
1431
1432sub rewrite_numbers
1433{
1434 (*OUT,$name,*nums,@symbols)=@_;
1435 my $thing;
1436
62dc5aad 1437 my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
948d0125
RL
1438 my $r; my %r; my %rsyms;
1439 foreach $r (@r) {
1440 (my $s, my $i) = split /\\/, $r;
1441 my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1442 $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1443 $r{$a} = $s."\\".$i;
1444 $rsyms{$s} = 1;
1445 }
1446
451e60e9
RL
1447 my %syms = ();
1448 foreach $_ (@symbols) {
1449 (my $n, my $i) = split /\\/;
1450 $syms{$n} = 1;
1451 }
1452
89eeccac
RL
1453 my @s=sort {
1454 &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n")
1455 || $a cmp $b
1456 } keys %nums;
948d0125 1457 foreach $sym (@s) {
3addf183 1458 (my $n, my $vers, my $i) = split /\\/, $nums{$sym};
948d0125
RL
1459 next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/;
1460 next if defined($rsyms{$sym});
62dc5aad 1461 print STDERR "DEBUG: rewrite_numbers for sym = ",$sym,": i = ",$i,", n = ",$n,", rsym{sym} = ",$rsyms{$sym},"syms{sym} = ",$syms{$sym},"\n" if $debug;
451e60e9
RL
1462 $i="NOEXIST::FUNCTION:"
1463 if !defined($i) || $i eq "" || !defined($syms{$sym});
62dc5aad
RL
1464 my $s2 = $sym;
1465 $s2 =~ s/\{[0-9]+\}$//;
3addf183 1466 printf OUT "%s%-39s %d\t%s\t%s\n","",$s2,$n,$vers,$i;
948d0125
RL
1467 if (exists $r{$sym}) {
1468 (my $s, $i) = split /\\/,$r{$sym};
62dc5aad
RL
1469 my $s2 = $s;
1470 $s2 =~ s/\{[0-9]+\}$//;
3addf183 1471 printf OUT "%s%-39s %d\t%s\t%s\n","",$s2,$n,$vers,$i;
948d0125
RL
1472 }
1473 }
1474}
1475
55a9cc6e 1476sub update_numbers
47339f61 1477{
948d0125
RL
1478 (*OUT,$name,*nums,my $start_num, my @symbols)=@_;
1479 my $new_syms = 0;
3addf183
MC
1480 my $basevers;
1481 my $vers;
1482
1483 ($basevers, $vers) = get_openssl_version();
948d0125 1484
62dc5aad 1485 my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
948d0125
RL
1486 my $r; my %r; my %rsyms;
1487 foreach $r (@r) {
1488 (my $s, my $i) = split /\\/, $r;
1489 my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1490 $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1491 $r{$a} = $s."\\".$i;
1492 $rsyms{$s} = 1;
1493 }
1494
1495 foreach $sym (@symbols) {
1496 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1497 next if $i =~ /^.*?:.*?:\w+\(\w+\)/;
1498 next if defined($rsyms{$sym});
1499 die "ERROR: Symbol $sym had no info attached to it."
1500 if $i eq "";
1501 if (!exists $nums{$s}) {
1502 $new_syms++;
62dc5aad
RL
1503 my $s2 = $s;
1504 $s2 =~ s/\{[0-9]+\}$//;
3addf183 1505 printf OUT "%s%-39s %d\t%s\t%s\n","",$s2, ++$start_num,$vers,$i;
948d0125 1506 if (exists $r{$s}) {
33b1a4c2 1507 ($s, $i) = split /\\/,$r{$s};
62dc5aad 1508 $s =~ s/\{[0-9]+\}$//;
3addf183 1509 printf OUT "%s%-39s %d\t%s\t%s\n","",$s, $start_num,$vers,$i;
948d0125 1510 }
55a9cc6e 1511 }
47339f61 1512 }
948d0125 1513 if($new_syms) {
cc373a37 1514 print STDERR "$name: Added $new_syms new symbols\n";
55a9cc6e 1515 } else {
cc373a37 1516 print STDERR "$name: No new symbols added\n";
948d0125
RL
1517 }
1518}
1519
1520sub check_existing
1521{
1522 (*nums, my @symbols)=@_;
1523 my %existing; my @remaining;
1524 @remaining=();
1525 foreach $sym (@symbols) {
1526 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1527 $existing{$s}=1;
1528 }
1529 foreach $sym (keys %nums) {
1530 if (!exists $existing{$sym}) {
1531 push @remaining, $sym;
1532 }
1533 }
1534 if(@remaining) {
1535 print STDERR "The following symbols do not seem to exist:\n";
1536 foreach $sym (@remaining) {
1537 print STDERR "\t",$sym,"\n";
1538 }
55a9cc6e 1539 }
47339f61 1540}
948d0125 1541
07c4c14c
MC
1542sub count_parens
1543{
1544 my $line = shift(@_);
1545
1546 my $open = $line =~ tr/\(//;
1547 my $close = $line =~ tr/\)//;
1548
1549 return $open - $close;
1550}
1551
e863d920
MC
1552#Parse opensslv.h to get the current version number. Also work out the base
1553#version, i.e. the lowest version number that is binary compatible with this
1554#version
1555sub get_openssl_version()
1556{
d7465918
RL
1557 my $fn = catfile($config{sourcedir},"include","openssl","opensslv.h");
1558 open (IN, "$fn") || die "Can't open opensslv.h";
e863d920
MC
1559
1560 while(<IN>) {
1561 if (/OPENSSL_VERSION_TEXT\s+"OpenSSL (\d\.\d\.)(\d[a-z]*)(-| )/) {
1562 my $suffix = $2;
56afc187 1563 (my $baseversion = $1) =~ s/\./_/g;
e863d920
MC
1564 close IN;
1565 return ($baseversion."0", $baseversion.$suffix);
1566 }
1567 }
1568 die "Can't find OpenSSL version number\n";
1569}
1570
1571#Given an OpenSSL version number, calculate the next version number. If the
1572#version number gets to a.b.czz then we go to a.b.(c+1)
1573sub get_next_version()
1574{
1575 my $thisversion = shift;
1576
1577 my ($base, $letter) = $thisversion =~ /^(\d_\d_\d)([a-z]{0,2})$/;
1578
1579 if ($letter eq "zz") {
1580 my $lastnum = substr($base, -1);
1581 return substr($base, 0, length($base)-1).(++$lastnum);
1582 }
1583 return $base.get_next_letter($letter);
1584}
1585
1586#Given the letters off the end of an OpenSSL version string, calculate what
1587#the letters for the next release would be.
1588sub get_next_letter()
1589{
1590 my $thisletter = shift;
1591 my $baseletter = "";
1592 my $endletter;
1593
1594 if ($thisletter eq "") {
1595 return "a";
1596 }
1597 if ((length $thisletter) > 1) {
1598 ($baseletter, $endletter) = $thisletter =~ /([a-z]+)([a-z])/;
1599 } else {
1600 $endletter = $thisletter;
1601 }
1602
1603 if ($endletter eq "z") {
1604 return $thisletter."a";
1605 } else {
1606 return $baseletter.(++$endletter);
1607 }
1608}
1609
1610#Check if a version is less than or equal to the current version. Its a fatal
1611#error if not. They must also only differ in letters, or the last number (i.e.
1612#the first two numbers must be the same)
1613sub check_version_lte()
1614{
1615 my ($testversion, $currversion) = @_;
1616 my $lentv;
1617 my $lencv;
1618 my $cvbase;
1619
1620 my ($cvnums) = $currversion =~ /^(\d_\d_\d)[a-z]*$/;
1621 my ($tvnums) = $testversion =~ /^(\d_\d_\d)[a-z]*$/;
1622
1623 #Die if we can't parse the version numbers or they don't look sane
1624 die "Invalid version number: $testversion and $currversion\n"
1625 if (!defined($cvnums) || !defined($tvnums)
1626 || length($cvnums) != 5
1627 || length($tvnums) != 5);
1628
1629 #If the base versions (without letters) don't match check they only differ
1630 #in the last number
1631 if ($cvnums ne $tvnums) {
1632 die "Invalid version number: $testversion "
1633 ."for current version $currversion\n"
1634 if (substr($cvnums, -1) < substr($tvnums, -1)
1635 || substr($cvnums, 0, 4) ne substr($tvnums, 0, 4));
1636 return;
1637 }
1638 #If we get here then the base version (i.e. the numbers) are the same - they
1639 #only differ in the letters
1640
1641 $lentv = length $testversion;
1642 $lencv = length $currversion;
1643
1644 #If the testversion has more letters than the current version then it must
1645 #be later (or malformed)
1646 if ($lentv > $lencv) {
1647 die "Invalid version number: $testversion "
1648 ."is greater than $currversion\n";
1649 }
1650
1651 #Get the last letter from the current version
1652 my ($cvletter) = $currversion =~ /([a-z])$/;
1653 if (defined $cvletter) {
1654 ($cvbase) = $currversion =~ /(\d_\d_\d[a-z]*)$cvletter$/;
1655 } else {
1656 $cvbase = $currversion;
1657 }
1658 die "Unable to parse version number $currversion" if (!defined $cvbase);
1659 my $tvbase;
1660 my ($tvletter) = $testversion =~ /([a-z])$/;
1661 if (defined $tvletter) {
1662 ($tvbase) = $testversion =~ /(\d_\d_\d[a-z]*)$tvletter$/;
1663 } else {
1664 $tvbase = $testversion;
1665 }
1666 die "Unable to parse version number $testversion" if (!defined $tvbase);
1667
1668 if ($lencv > $lentv) {
1669 #If current version has more letters than testversion then testversion
1670 #minus the final letter must be a substring of the current version
1671 die "Invalid version number $testversion "
1672 ."is greater than $currversion or is invalid\n"
1673 if (index($cvbase, $tvbase) != 0);
1674 } else {
1675 #If both versions have the same number of letters then they must be
1676 #equal up to the last letter, and the last letter in testversion must
1677 #be less than or equal to the last letter in current version.
1678 die "Invalid version number $testversion "
1679 ."is greater than $currversion\n"
1680 if (($cvbase ne $tvbase) && ($tvletter gt $cvletter));
1681 }
1682}
7a556fb6
DSH
1683
1684sub do_deprecated()
1685{
1686 my ($decl, $plats, $algs) = @_;
ca0004e5
VD
1687 $decl =~ /^\s*(DEPRECATEDIN_\d+_\d+_\d+)\s*\((.*)\)\s*$/
1688 or die "Bad DEPRECTEDIN: $decl\n";
7a556fb6
DSH
1689 my $info1 .= "#INFO:";
1690 $info1 .= join(',', @{$plats}) . ":";
1691 my $info2 = $info1;
1692 $info1 .= join(',',@{$algs}, $1) . ";";
1693 $info2 .= join(',',@{$algs}) . ";";
1694 return $info1 . $2 . ";" . $info2;
1695}