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