]> git.ipfire.org Git - thirdparty/openssl.git/blame - util/mkdef.pl
AppVeyor: Only use the latest VS version
[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#
6928b617 8# Intermediary files are created, call libcrypto.num and libssl.num,
1a53f1d6 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
6928b617
RL
47my $crypto_num= catfile($config{sourcedir},"util","libcrypto.num");
48my $ssl_num= catfile($config{sourcedir},"util","libssl.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
6928b617 162 $do_ssl=1 if $_ eq "libssl";
cd4c36ad
RL
163 if ($_ eq "ssl") {
164 $do_ssl=1;
165 $libname=$_
166 }
6928b617 167 $do_crypto=1 if $_ eq "libcrypto";
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) {
6928b617 205 $libname="LIBSSL";
cd4c36ad
RL
206 }
207 if ($do_crypto) {
6928b617 208 $libname="LIBCRYPTO";
cd4c36ad
RL
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";
7f5f4102 298$crypto.=" include/openssl/kdf.h";
d02b48c6 299
dee502be 300my $symhacks="include/openssl/symhacks.h";
55a9cc6e 301
6928b617
RL
302my @ssl_symbols = &do_defs("LIBSSL", $ssl, $symhacks);
303my @crypto_symbols = &do_defs("LIBCRYPTO", $crypto, $symhacks);
47339f61 304
55a9cc6e
DSH
305if ($do_update) {
306
307if ($do_ssl == 1) {
948d0125 308
6928b617 309 &maybe_add_info("LIBSSL",*ssl_list,@ssl_symbols);
948d0125
RL
310 if ($do_rewrite == 1) {
311 open(OUT, ">$ssl_num");
6928b617 312 &rewrite_numbers(*OUT,"LIBSSL",*ssl_list,@ssl_symbols);
948d0125
RL
313 } else {
314 open(OUT, ">>$ssl_num");
315 }
6928b617 316 &update_numbers(*OUT,"LIBSSL",*ssl_list,$max_ssl,@ssl_symbols);
55a9cc6e
DSH
317 close OUT;
318}
319
320if($do_crypto == 1) {
948d0125 321
6928b617 322 &maybe_add_info("LIBCRYPTO",*crypto_list,@crypto_symbols);
948d0125
RL
323 if ($do_rewrite == 1) {
324 open(OUT, ">$crypto_num");
6928b617 325 &rewrite_numbers(*OUT,"LIBCRYPTO",*crypto_list,@crypto_symbols);
948d0125
RL
326 } else {
327 open(OUT, ">>$crypto_num");
328 }
6928b617 329 &update_numbers(*OUT,"LIBCRYPTO",*crypto_list,$max_crypto,@crypto_symbols);
55a9cc6e 330 close OUT;
12aefe78
DSH
331}
332
c47c6196
DSH
333} elsif ($do_checkexist) {
334 &check_existing(*ssl_list, @ssl_symbols)
335 if $do_ssl == 1;
336 &check_existing(*crypto_list, @crypto_symbols)
337 if $do_crypto == 1;
967f4ca8 338} elsif ($do_ctest || $do_ctestall) {
12aefe78
DSH
339
340 print <<"EOF";
341
342/* Test file to check all DEF file symbols are present by trying
343 * to link to all of them. This is *not* intended to be run!
344 */
345
346int main()
347{
348EOF
6928b617 349 &print_test_file(*STDOUT,"LIBSSL",*ssl_list,$do_ctestall,@ssl_symbols)
12aefe78
DSH
350 if $do_ssl == 1;
351
6928b617 352 &print_test_file(*STDOUT,"LIBCRYPTO",*crypto_list,$do_ctestall,@crypto_symbols)
12aefe78
DSH
353 if $do_crypto == 1;
354
355 print "}\n";
55a9cc6e
DSH
356
357} else {
8cf65228 358
cd4c36ad 359 &print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
55a9cc6e
DSH
360 if $do_ssl == 1;
361
cd4c36ad 362 &print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
55a9cc6e 363 if $do_crypto == 1;
8cf65228 364
55a9cc6e 365}
d02b48c6 366
d02b48c6
RE
367
368sub do_defs
47339f61 369{
948d0125 370 my($name,$files,$symhacksfile)=@_;
0f583f69 371 my $file;
47339f61 372 my @ret;
948d0125
RL
373 my %syms;
374 my %platform; # For anything undefined, we assume ""
375 my %kind; # For anything undefined, we assume "FUNCTION"
376 my %algorithm; # For anything undefined, we assume ""
62dc5aad
RL
377 my %variant;
378 my %variant_cnt; # To be able to allocate "name{n}" if "name"
379 # is the same name as the original.
0f583f69 380 my $cpp;
3f07fe09 381 my %unknown_algorithms = ();
07c4c14c 382 my $parens = 0;
d02b48c6 383
948d0125 384 foreach $file (split(/\s+/,$symhacksfile." ".$files))
d02b48c6 385 {
d7465918
RL
386 my $fn = catfile($config{sourcedir},$file);
387 print STDERR "DEBUG: starting on $fn:\n" if $debug;
388 open(IN,"<$fn") || die "unable to open $fn:$!\n";
0f583f69 389 my $line = "", my $def= "";
47339f61 390 my %tag = (
d399fdf8
RL
391 (map { $_ => 0 } @known_platforms),
392 (map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
cf1b7d96 393 (map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
07c4c14c 394 (map { "OPENSSL_USE_".$_ => 0 } @known_algorithms),
47339f61 395 NOPROTO => 0,
47339f61
DSH
396 PERL5 => 0,
397 _WINDLL => 0,
47339f61
DSH
398 CONST_STRICT => 0,
399 TRUE => 1,
400 );
948d0125 401 my $symhacking = $file eq $symhacksfile;
267a1927
RL
402 my @current_platforms = ();
403 my @current_algorithms = ();
404
62dc5aad
RL
405 # params: symbol, alias, platforms, kind
406 # The reason to put this subroutine in a variable is that
407 # it will otherwise create it's own, unshared, version of
408 # %tag and %variant...
409 my $make_variant = sub
410 {
411 my ($s, $a, $p, $k) = @_;
412 my ($a1, $a2);
413
414 print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
415 if (defined($p))
416 {
417 $a1 = join(",",$p,
418 grep(!/^$/,
419 map { $tag{$_} == 1 ? $_ : "" }
420 @known_platforms));
421 }
422 else
423 {
424 $a1 = join(",",
425 grep(!/^$/,
426 map { $tag{$_} == 1 ? $_ : "" }
427 @known_platforms));
428 }
429 $a2 = join(",",
430 grep(!/^$/,
431 map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
432 @known_ossl_platforms));
433 print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
434 if ($a1 eq "") { $a1 = $a2; }
435 elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
436 if ($a eq $s)
437 {
438 if (!defined($variant_cnt{$s}))
439 {
440 $variant_cnt{$s} = 0;
441 }
442 $variant_cnt{$s}++;
443 $a .= "{$variant_cnt{$s}}";
444 }
c454dbcd
RL
445 my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
446 my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
447 if (!grep(/^$togrep$/,
448 split(/;/, defined($variant{$s})?$variant{$s}:""))) {
449 if (defined($variant{$s})) { $variant{$s} .= ";"; }
450 $variant{$s} .= $toadd;
451 }
62dc5aad
RL
452 print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
453 };
454
455 print STDERR "DEBUG: parsing ----------\n" if $debug;
47339f61 456 while(<IN>) {
07c4c14c 457 if($parens > 0) {
7a556fb6 458 #Inside a DEPRECATEDIN
fa327faf 459 $stored_multiline .= $_;
9ba96fbb 460 $stored_multiline =~ s|\R$||; # Better chomp
7a556fb6 461 print STDERR "DEBUG: Continuing multiline DEPRECATEDIN: $stored_multiline\n" if $debug;
fa327faf
RL
462 $parens = count_parens($stored_multiline);
463 if ($parens == 0) {
7a556fb6
DSH
464 $def .= do_deprecated($stored_multiline,
465 \@current_platforms,
466 \@current_algorithms);
fa327faf 467 }
07c4c14c
MC
468 next;
469 }
40e950ae
DSH
470 if (/\/\* Error codes for the \w+ functions\. \*\//)
471 {
472 undef @tag;
473 last;
474 }
47339f61
DSH
475 if ($line ne '') {
476 $_ = $line . $_;
477 $line = '';
d02b48c6 478 }
47339f61
DSH
479
480 if (/\\$/) {
9ba96fbb 481 $line = $`; # keep what was before the backslash
47339f61
DSH
482 next;
483 }
484
68e57536
AP
485 if(/\/\*/) {
486 if (not /\*\//) { # multiline comment...
487 $line = $_; # ... just accumulate
488 next;
489 } else {
490 s/\/\*.*?\*\///gs;# wipe it
491 }
492 }
493
47339f61 494 if ($cpp) {
68e57536
AP
495 $cpp++ if /^#\s*if/;
496 $cpp-- if /^#\s*endif/;
47339f61 497 next;
9ba96fbb 498 }
d9706f19
MC
499 if (/^#.*ifdef.*cplusplus/) {
500 $cpp = 1;
501 next;
502 }
47339f61 503
47339f61 504 s/{[^{}]*}//gs; # ignore {} blocks
6cb68620 505 print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
d399fdf8 506 print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
3f07fe09 507 if (/^\#\s*ifndef\s+(.*)/) {
d399fdf8 508 push(@tag,"-");
d02b48c6
RE
509 push(@tag,$1);
510 $tag{$1}=-1;
d399fdf8 511 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
3f07fe09 512 } elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
d399fdf8
RL
513 push(@tag,"-");
514 if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
515 my $tmp_1 = $1;
516 my $tmp_;
517 foreach $tmp_ (split '\&\&',$tmp_1) {
518 $tmp_ =~ /!defined\(([^\)]+)\)/;
519 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
520 push(@tag,$1);
521 $tag{$1}=-1;
522 }
523 } else {
524 print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
525 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
526 push(@tag,$1);
527 $tag{$1}=-1;
528 }
8aa36bca 529 } elsif (/^\#\s*ifdef\s+(\S*)/) {
d399fdf8 530 push(@tag,"-");
d02b48c6
RE
531 push(@tag,$1);
532 $tag{$1}=1;
d399fdf8 533 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
3f07fe09 534 } elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
d399fdf8
RL
535 push(@tag,"-");
536 if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
537 my $tmp_1 = $1;
538 my $tmp_;
539 foreach $tmp_ (split '\|\|',$tmp_1) {
540 $tmp_ =~ /defined\(([^\)]+)\)/;
541 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
542 push(@tag,$1);
543 $tag{$1}=1;
544 }
545 } else {
546 print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
547 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
548 push(@tag,$1);
549 $tag{$1}=1;
550 }
948d0125 551 } elsif (/^\#\s*error\s+(\w+) is disabled\./) {
d399fdf8
RL
552 my $tag_i = $#tag;
553 while($tag[$tag_i] ne "-") {
554 if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
555 $tag{$tag[$tag_i]}=2;
556 print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
557 }
558 $tag_i--;
948d0125 559 }
47339f61 560 } elsif (/^\#\s*endif/) {
d399fdf8 561 my $tag_i = $#tag;
665560e9 562 while($tag_i > 0 && $tag[$tag_i] ne "-") {
d399fdf8
RL
563 my $t=$tag[$tag_i];
564 print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
565 if ($tag{$t}==2) {
566 $tag{$t}=-1;
567 } else {
568 $tag{$t}=0;
569 }
570 print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
571 pop(@tag);
572 if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
573 $t=$1;
07c4c14c
MC
574 } elsif($t =~ /^OPENSSL_USE_([A-Z0-9_]+)$/) {
575 $t=$1;
d399fdf8
RL
576 } else {
577 $t="";
578 }
579 if ($t ne ""
580 && !grep(/^$t$/, @known_algorithms)) {
581 $unknown_algorithms{$t} = 1;
582 #print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
583 }
584 $tag_i--;
948d0125 585 }
d02b48c6 586 pop(@tag);
47339f61 587 } elsif (/^\#\s*else/) {
d399fdf8 588 my $tag_i = $#tag;
d9706f19 589 die "$file unmatched else\n" if $tag_i < 0;
d399fdf8
RL
590 while($tag[$tag_i] ne "-") {
591 my $t=$tag[$tag_i];
592 $tag{$t}= -$tag{$t};
593 print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
594 $tag_i--;
595 }
47339f61 596 } elsif (/^\#\s*if\s+1/) {
d399fdf8 597 push(@tag,"-");
47339f61
DSH
598 # Dummy tag
599 push(@tag,"TRUE");
600 $tag{"TRUE"}=1;
d399fdf8 601 print STDERR "DEBUG: $file: found 1\n" if $debug;
1e414935 602 } elsif (/^\#\s*if\s+0/) {
d399fdf8 603 push(@tag,"-");
1e414935
BM
604 # Dummy tag
605 push(@tag,"TRUE");
606 $tag{"TRUE"}=-1;
d399fdf8 607 print STDERR "DEBUG: $file: found 0\n" if $debug;
d9706f19
MC
608 } elsif (/^\#\s*if\s+/) {
609 #Some other unrecognized "if" style
610 push(@tag,"-");
948d0125 611 } elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
2ae87d46 612 && $symhacking && $tag{'TRUE'} != -1) {
62dc5aad
RL
613 # This is for aliasing. When we find an alias,
614 # we have to invert
615 &$make_variant($1,$2);
616 print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
948d0125
RL
617 }
618 if (/^\#/) {
267a1927
RL
619 @current_platforms =
620 grep(!/^$/,
d399fdf8
RL
621 map { $tag{$_} == 1 ? $_ :
622 $tag{$_} == -1 ? "!".$_ : "" }
267a1927 623 @known_platforms);
d399fdf8
RL
624 push @current_platforms
625 , grep(!/^$/,
626 map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
627 $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_ : "" }
628 @known_ossl_platforms);
07c4c14c 629 @current_algorithms = ();
267a1927
RL
630 @current_algorithms =
631 grep(!/^$/,
cf1b7d96 632 map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
267a1927 633 @known_algorithms);
07c4c14c
MC
634 push @current_algorithms
635 , grep(!/^$/,
636 map { $tag{"OPENSSL_USE_".$_} == 1 ? $_ : "" }
637 @known_algorithms);
267a1927
RL
638 $def .=
639 "#INFO:"
640 .join(',',@current_platforms).":"
641 .join(',',@current_algorithms).";";
47339f61
DSH
642 next;
643 }
2ae87d46 644 if ($tag{'TRUE'} != -1) {
b32166b4
MC
645 if (/^\s*DEFINE_STACK_OF\s*\(\s*(\w*)\s*\)/
646 || /^\s*DEFINE_STACK_OF_CONST\s*\(\s*(\w*)\s*\)/) {
2ae87d46
RL
647 next;
648 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
649 $def .= "int d2i_$3(void);";
650 $def .= "int i2d_$3(void);";
62dc5aad
RL
651 # Variant for platforms that do not
652 # have to access globale variables
653 # in shared libraries through functions
654 $def .=
655 "#INFO:"
656 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
657 .join(',',@current_algorithms).";";
2ae87d46 658 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
659 $def .=
660 "#INFO:"
661 .join(',',@current_platforms).":"
662 .join(',',@current_algorithms).";";
663 # Variant for platforms that have to
664 # access globale variables in shared
665 # libraries through functions
666 &$make_variant("$2_it","$2_it",
667 "EXPORT_VAR_AS_FUNCTION",
668 "FUNCTION");
2ae87d46
RL
669 next;
670 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
671 $def .= "int d2i_$3(void);";
672 $def .= "int i2d_$3(void);";
673 $def .= "int $3_free(void);";
674 $def .= "int $3_new(void);";
62dc5aad
RL
675 # Variant for platforms that do not
676 # have to access globale variables
677 # in shared libraries through functions
678 $def .=
679 "#INFO:"
680 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
681 .join(',',@current_algorithms).";";
2ae87d46 682 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
683 $def .=
684 "#INFO:"
685 .join(',',@current_platforms).":"
686 .join(',',@current_algorithms).";";
687 # Variant for platforms that have to
688 # access globale variables in shared
689 # libraries through functions
690 &$make_variant("$2_it","$2_it",
691 "EXPORT_VAR_AS_FUNCTION",
692 "FUNCTION");
693 next;
2ae87d46
RL
694 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
695 /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
696 $def .= "int d2i_$1(void);";
697 $def .= "int i2d_$1(void);";
698 $def .= "int $1_free(void);";
699 $def .= "int $1_new(void);";
62dc5aad
RL
700 # Variant for platforms that do not
701 # have to access globale variables
702 # in shared libraries through functions
703 $def .=
704 "#INFO:"
705 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
706 .join(',',@current_algorithms).";";
2ae87d46 707 $def .= "OPENSSL_EXTERN int $1_it;";
62dc5aad
RL
708 $def .=
709 "#INFO:"
710 .join(',',@current_platforms).":"
711 .join(',',@current_algorithms).";";
712 # Variant for platforms that have to
713 # access globale variables in shared
714 # libraries through functions
715 &$make_variant("$1_it","$1_it",
716 "EXPORT_VAR_AS_FUNCTION",
717 "FUNCTION");
2ae87d46
RL
718 next;
719 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
720 $def .= "int d2i_$2(void);";
721 $def .= "int i2d_$2(void);";
62dc5aad
RL
722 # Variant for platforms that do not
723 # have to access globale variables
724 # in shared libraries through functions
725 $def .=
726 "#INFO:"
727 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
728 .join(',',@current_algorithms).";";
2ae87d46 729 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
730 $def .=
731 "#INFO:"
732 .join(',',@current_platforms).":"
733 .join(',',@current_algorithms).";";
734 # Variant for platforms that have to
735 # access globale variables in shared
736 # libraries through functions
737 &$make_variant("$2_it","$2_it",
738 "EXPORT_VAR_AS_FUNCTION",
739 "FUNCTION");
2ae87d46 740 next;
ea3675b5
DSH
741 } elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
742 $def .= "int $1_free(void);";
743 $def .= "int $1_new(void);";
744 next;
2ae87d46
RL
745 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
746 $def .= "int d2i_$2(void);";
747 $def .= "int i2d_$2(void);";
748 $def .= "int $2_free(void);";
749 $def .= "int $2_new(void);";
62dc5aad
RL
750 # Variant for platforms that do not
751 # have to access globale variables
752 # in shared libraries through functions
753 $def .=
754 "#INFO:"
755 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
756 .join(',',@current_algorithms).";";
2ae87d46 757 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
758 $def .=
759 "#INFO:"
760 .join(',',@current_platforms).":"
761 .join(',',@current_algorithms).";";
762 # Variant for platforms that have to
763 # access globale variables in shared
764 # libraries through functions
765 &$make_variant("$2_it","$2_it",
766 "EXPORT_VAR_AS_FUNCTION",
767 "FUNCTION");
2ae87d46 768 next;
62dc5aad
RL
769 } elsif (/^\s*DECLARE_ASN1_ITEM\s*\(\s*(\w*)\s*\)/) {
770 # Variant for platforms that do not
771 # have to access globale variables
772 # in shared libraries through functions
773 $def .=
774 "#INFO:"
775 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
776 .join(',',@current_algorithms).";";
2ae87d46 777 $def .= "OPENSSL_EXTERN int $1_it;";
62dc5aad
RL
778 $def .=
779 "#INFO:"
780 .join(',',@current_platforms).":"
781 .join(',',@current_algorithms).";";
782 # Variant for platforms that have to
783 # access globale variables in shared
784 # libraries through functions
785 &$make_variant("$1_it","$1_it",
786 "EXPORT_VAR_AS_FUNCTION",
787 "FUNCTION");
2ae87d46 788 next;
f86abc2e 789 } elsif (/^\s*DECLARE_ASN1_NDEF_FUNCTION\s*\(\s*(\w*)\s*\)/) {
97ebe047 790 $def .= "int i2d_$1_NDEF(void);";
2ae87d46
RL
791 } elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
792 next;
16094305
DSH
793 } elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION\s*\(\s*(\w*)\s*\)/) {
794 $def .= "int $1_print_ctx(void);";
795 next;
796 } elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
797 $def .= "int $2_print_ctx(void);";
798 next;
62dc5aad
RL
799 } elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) {
800 next;
2ae87d46 801 } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
47738cba
AP
802 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ||
803 /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
804 $def .=
805 "#INFO:"
6d23cf97 806 .join(',',@current_platforms).":"
2ae87d46
RL
807 .join(',',@current_algorithms).";";
808 $def .= "int PEM_read_$1(void);";
809 $def .= "int PEM_write_$1(void);";
810 $def .=
811 "#INFO:"
812 .join(',',@current_platforms).":"
813 .join(',',@current_algorithms).";";
814 # Things that are everywhere
815 $def .= "int PEM_read_bio_$1(void);";
816 $def .= "int PEM_write_bio_$1(void);";
817 next;
818 } elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
e43bfb29 819 /^DECLARE_PEM_write_const\s*\(\s*(\w*)\s*,/ ||
2ae87d46 820 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
821 $def .=
822 "#INFO:"
6d23cf97 823 .join(',',@current_platforms).":"
2ae87d46
RL
824 .join(',',@current_algorithms).";";
825 $def .= "int PEM_write_$1(void);";
826 $def .=
827 "#INFO:"
828 .join(',',@current_platforms).":"
829 .join(',',@current_algorithms).";";
830 # Things that are everywhere
831 $def .= "int PEM_write_bio_$1(void);";
832 next;
833 } elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
834 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
835 $def .=
836 "#INFO:"
6d23cf97 837 .join(',',@current_platforms).":"
2ae87d46
RL
838 .join(',',@current_algorithms).";";
839 $def .= "int PEM_read_$1(void);";
840 $def .=
841 "#INFO:"
842 .join(',',@current_platforms).":"
843 .join(',',@current_algorithms).";";
844 # Things that are everywhere
845 $def .= "int PEM_read_bio_$1(void);";
846 next;
62dc5aad
RL
847 } elsif (/^OPENSSL_DECLARE_GLOBAL\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
848 # Variant for platforms that do not
849 # have to access globale variables
850 # in shared libraries through functions
851 $def .=
852 "#INFO:"
853 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
854 .join(',',@current_algorithms).";";
855 $def .= "OPENSSL_EXTERN int _shadow_$2;";
856 $def .=
857 "#INFO:"
858 .join(',',@current_platforms).":"
859 .join(',',@current_algorithms).";";
860 # Variant for platforms that have to
861 # access globale variables in shared
862 # libraries through functions
863 &$make_variant("_shadow_$2","_shadow_$2",
864 "EXPORT_VAR_AS_FUNCTION",
865 "FUNCTION");
7a556fb6 866 } elsif (/^\s*DEPRECATEDIN/) {
07c4c14c 867 $parens = count_parens($_);
fa327faf 868 if ($parens == 0) {
7a556fb6
DSH
869 $def .= do_deprecated($_,
870 \@current_platforms,
871 \@current_algorithms);
fa327faf
RL
872 } else {
873 $stored_multiline = $_;
9ba96fbb 874 $stored_multiline =~ s|\R$||;
7a556fb6 875 print STDERR "DEBUG: Found multiline DEPRECATEDIN starting with: $stored_multiline\n" if $debug;
fa327faf
RL
876 next;
877 }
2ae87d46 878 } elsif ($tag{'CONST_STRICT'} != 1) {
948d0125 879 if (/\{|\/\*|\([^\)]*$/) {
47339f61
DSH
880 $line = $_;
881 } else {
882 $def .= $_;
883 }
d02b48c6
RE
884 }
885 }
2ae87d46 886 }
d02b48c6 887 close(IN);
d9706f19 888 die "$file: Unmatched tags\n" if $#tag >= 0;
47339f61 889
948d0125
RL
890 my $algs;
891 my $plays;
892
62dc5aad 893 print STDERR "DEBUG: postprocessing ----------\n" if $debug;
47339f61 894 foreach (split /;/, $def) {
948d0125 895 my $s; my $k = "FUNCTION"; my $p; my $a;
47339f61
DSH
896 s/^[\n\s]*//g;
897 s/[\n\s]*$//g;
948d0125 898 next if(/\#undef/);
47339f61 899 next if(/typedef\W/);
948d0125
RL
900 next if(/\#define/);
901
68e57536
AP
902 # Reduce argument lists to empty ()
903 # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
904 while(/\(.*\)/s) {
905 s/\([^\(\)]+\)/\{\}/gs;
906 s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
907 }
908 # pretend as we didn't use curly braces: {} -> ()
909 s/\{\}/\(\)/gs;
910
911 s/STACK_OF\(\)/void/gs;
174c86a2 912 s/LHASH_OF\(\)/void/gs;
68e57536 913
62dc5aad 914 print STDERR "DEBUG: \$_ = \"$_\"\n" if $debug;
948d0125
RL
915 if (/^\#INFO:([^:]*):(.*)$/) {
916 $plats = $1;
917 $algs = $2;
89eeccac 918 print STDERR "DEBUG: found info on platforms ($plats) and algorithms ($algs)\n" if $debug;
948d0125 919 next;
62dc5aad 920 } elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+(\{[0-9]+\})?)(\[[0-9]*\])*\s*$/) {
948d0125
RL
921 $s = $1;
922 $k = "VARIABLE";
89eeccac 923 print STDERR "DEBUG: found external variable $s\n" if $debug;
68e57536 924 } elsif (/TYPEDEF_\w+_OF/s) {
47339f61 925 next;
68e57536
AP
926 } elsif (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
927 $s = $1; # a function name!
89eeccac 928 print STDERR "DEBUG: found function $s\n" if $debug;
47339f61
DSH
929 } elsif (/\(/ and not (/=/)) {
930 print STDERR "File $file: cannot parse: $_;\n";
948d0125
RL
931 next;
932 } else {
933 next;
934 }
935
936 $syms{$s} = 1;
937 $kind{$s} = $k;
938
939 $p = $plats;
940 $a = $algs;
948d0125 941
62dc5aad
RL
942 $platform{$s} =
943 &reduce_platforms((defined($platform{$s})?$platform{$s}.',':"").$p);
948d0125
RL
944 $algorithm{$s} .= ','.$a;
945
62dc5aad 946 if (defined($variant{$s})) {
c454dbcd
RL
947 foreach $v (split /;/,$variant{$s}) {
948 (my $r, my $p, my $k) = split(/:/,$v);
949 my $ip = join ',',map({ /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p);
950 $syms{$r} = 1;
951 if (!defined($k)) { $k = $kind{$s}; }
952 $kind{$r} = $k."(".$s.")";
953 $algorithm{$r} = $algorithm{$s};
954 $platform{$r} = &reduce_platforms($platform{$s}.",".$p.",".$p);
955 $platform{$s} = &reduce_platforms($platform{$s}.','.$ip.','.$ip);
956 print STDERR "DEBUG: \$variant{\"$s\"} = ",$v,"; \$r = $r; \$p = ",$platform{$r},"; \$a = ",$algorithm{$r},"; \$kind = ",$kind{$r},"\n" if $debug;
957 }
47339f61 958 }
62dc5aad 959 print STDERR "DEBUG: \$s = $s; \$p = ",$platform{$s},"; \$a = ",$algorithm{$s},"; \$kind = ",$kind{$s},"\n" if $debug;
d02b48c6 960 }
d02b48c6
RE
961 }
962
948d0125 963 # Prune the returned symbols
47339f61 964
948d0125 965 delete $syms{"bn_dump1"};
6d23cf97 966 $platform{"BIO_s_log"} .= ",!WIN32,!macintosh";
948d0125 967
2ae87d46
RL
968 $platform{"PEM_read_NS_CERT_SEQ"} = "VMS";
969 $platform{"PEM_write_NS_CERT_SEQ"} = "VMS";
970 $platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
971 $platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
af55c09d
RL
972 $platform{"EVP_sha384"} = "!VMSVAX";
973 $platform{"EVP_sha512"} = "!VMSVAX";
974 $platform{"SHA384_Init"} = "!VMSVAX";
975 $platform{"SHA384_Transform"} = "!VMSVAX";
976 $platform{"SHA384_Update"} = "!VMSVAX";
977 $platform{"SHA384_Final"} = "!VMSVAX";
978 $platform{"SHA384"} = "!VMSVAX";
979 $platform{"SHA512_Init"} = "!VMSVAX";
980 $platform{"SHA512_Transform"} = "!VMSVAX";
981 $platform{"SHA512_Update"} = "!VMSVAX";
982 $platform{"SHA512_Final"} = "!VMSVAX";
983 $platform{"SHA512"} = "!VMSVAX";
984
2ae87d46 985
948d0125
RL
986 # Info we know about
987
948d0125
RL
988 push @ret, map { $_."\\".&info_string($_,"EXIST",
989 $platform{$_},
990 $kind{$_},
991 $algorithm{$_}) } keys %syms;
992
3f07fe09
RL
993 if (keys %unknown_algorithms) {
994 print STDERR "WARNING: mkdef.pl doesn't know the following algorithms:\n";
995 print STDERR "\t",join("\n\t",keys %unknown_algorithms),"\n";
996 }
948d0125
RL
997 return(@ret);
998}
999
62dc5aad
RL
1000# Param: string of comma-separated platform-specs.
1001sub reduce_platforms
1002{
1003 my ($platforms) = @_;
948d0125
RL
1004 my $pl = defined($platforms) ? $platforms : "";
1005 my %p = map { $_ => 0 } split /,/, $pl;
948d0125
RL
1006 my $ret;
1007
62dc5aad
RL
1008 print STDERR "DEBUG: Entered reduce_platforms with \"$platforms\"\n"
1009 if $debug;
948d0125
RL
1010 # We do this, because if there's code like the following, it really
1011 # means the function exists in all cases and should therefore be
1012 # everywhere. By increasing and decreasing, we may attain 0:
1013 #
1014 # ifndef WIN16
1015 # int foo();
1016 # else
1017 # int _fat foo();
1018 # endif
1019 foreach $platform (split /,/, $pl) {
1020 if ($platform =~ /^!(.*)$/) {
1021 $p{$1}--;
1022 } else {
1023 $p{$platform}++;
d02b48c6 1024 }
47339f61 1025 }
948d0125
RL
1026 foreach $platform (keys %p) {
1027 if ($p{$platform} == 0) { delete $p{$platform}; }
d02b48c6
RE
1028 }
1029
948d0125 1030 delete $p{""};
62dc5aad 1031
c454dbcd 1032 $ret = join(',',sort(map { $p{$_} < 0 ? "!".$_ : $_ } keys %p));
62dc5aad
RL
1033 print STDERR "DEBUG: Exiting reduce_platforms with \"$ret\"\n"
1034 if $debug;
1035 return $ret;
1036}
1037
cc373a37
RS
1038sub info_string
1039{
62dc5aad
RL
1040 (my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_;
1041
1042 my %a = defined($algorithms) ?
1043 map { $_ => 1 } split /,/, $algorithms : ();
1044 my $k = defined($kind) ? $kind : "FUNCTION";
1045 my $ret;
1046 my $p = &reduce_platforms($platforms);
1047
948d0125 1048 delete $a{""};
d02b48c6 1049
948d0125 1050 $ret = $exist;
62dc5aad 1051 $ret .= ":".$p;
948d0125 1052 $ret .= ":".$k;
62dc5aad 1053 $ret .= ":".join(',',sort keys %a);
948d0125
RL
1054 return $ret;
1055}
1056
cc373a37
RS
1057sub maybe_add_info
1058{
948d0125
RL
1059 (my $name, *nums, my @symbols) = @_;
1060 my $sym;
1061 my $new_info = 0;
451e60e9 1062 my %syms=();
948d0125 1063
948d0125
RL
1064 foreach $sym (@symbols) {
1065 (my $s, my $i) = split /\\/, $sym;
948d0125 1066 if (defined($nums{$s})) {
62dc5aad 1067 $i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/;
3addf183 1068 (my $n, my $vers, my $dummy) = split /\\/, $nums{$s};
948d0125 1069 if (!defined($dummy) || $i ne $dummy) {
3addf183 1070 $nums{$s} = $n."\\".$vers."\\".$i;
948d0125 1071 $new_info++;
d399fdf8 1072 print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n" if $debug;
948d0125
RL
1073 }
1074 }
62dc5aad 1075 $syms{$s} = 1;
451e60e9
RL
1076 }
1077
1078 my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums;
1079 foreach $sym (@s) {
3addf183 1080 (my $n, my $vers, my $i) = split /\\/, $nums{$sym};
62dc5aad 1081 if (!defined($syms{$sym}) && $i !~ /^NOEXIST:/) {
451e60e9 1082 $new_info++;
62dc5aad 1083 print STDERR "DEBUG: maybe_add_info for $sym: -> undefined\n" if $debug;
451e60e9 1084 }
948d0125
RL
1085 }
1086 if ($new_info) {
cc373a37 1087 print STDERR "$name: $new_info old symbols have updated info\n";
6d50071e
RL
1088 if (!$do_rewrite) {
1089 print STDERR "You should do a rewrite to fix this.\n";
1090 }
948d0125 1091 } else {
948d0125 1092 }
47339f61 1093}
d02b48c6 1094
62dc5aad
RL
1095# Param: string of comma-separated keywords, each possibly prefixed with a "!"
1096sub is_valid
1097{
1098 my ($keywords_txt,$platforms) = @_;
1099 my (@keywords) = split /,/,$keywords_txt;
d3fdc27a 1100 my ($falsesum, $truesum) = (0, 1);
62dc5aad
RL
1101
1102 # Param: one keyword
1103 sub recognise
1104 {
1105 my ($keyword,$platforms) = @_;
1106
1107 if ($platforms) {
1108 # platforms
af55c09d
RL
1109 if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
1110 if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
62dc5aad
RL
1111 if ($keyword eq "VMS" && $VMS) { return 1; }
1112 if ($keyword eq "WIN32" && $W32) { return 1; }
62dc5aad 1113 if ($keyword eq "WINNT" && $NT) { return 1; }
cd4c36ad 1114 if ($keyword eq "OS2" && $OS2) { return 1; }
62dc5aad
RL
1115 # Special platforms:
1116 # EXPORT_VAR_AS_FUNCTION means that global variables
1117 # will be represented as functions. This currently
1118 # only happens on VMS-VAX.
6d23cf97 1119 if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32)) {
62dc5aad
RL
1120 return 1;
1121 }
8931b30d 1122 if ($keyword eq "ZLIB" && $zlib) { return 1; }
62dc5aad
RL
1123 return 0;
1124 } else {
1125 # algorithms
2854c798 1126 if ($disabled_algorithms{$keyword} == 1) { return 0;}
62dc5aad
RL
1127
1128 # Nothing recognise as true
1129 return 1;
1130 }
1131 }
1132
1133 foreach $k (@keywords) {
1134 if ($k =~ /^!(.*)$/) {
1135 $falsesum += &recognise($1,$platforms);
1136 } else {
d3fdc27a 1137 $truesum *= &recognise($k,$platforms);
62dc5aad
RL
1138 }
1139 }
1140 print STDERR "DEBUG: [",$#keywords,",",$#keywords < 0,"] is_valid($keywords_txt) => (\!$falsesum) && $truesum = ",(!$falsesum) && $truesum,"\n" if $debug;
1141 return (!$falsesum) && $truesum;
1142}
1143
12aefe78
DSH
1144sub print_test_file
1145{
62dc5aad 1146 (*OUT,my $name,*nums,my $testall,my @symbols)=@_;
0f583f69 1147 my $n = 1; my @e; my @r;
948d0125
RL
1148 my $sym; my $prev = ""; my $prefSSLeay;
1149
62dc5aad
RL
1150 (@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
1151 (@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:.*/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
948d0125
RL
1152 @symbols=((sort @e),(sort @r));
1153
1154 foreach $sym (@symbols) {
1155 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
62dc5aad
RL
1156 my $v = 0;
1157 $v = 1 if $i=~ /^.*?:.*?:VARIABLE/;
1158 my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1159 my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1160 if (!defined($nums{$s})) {
1161 print STDERR "Warning: $s does not have a number assigned\n"
1162 if(!$do_update);
1163 } elsif (is_valid($p,1) && is_valid($a,0)) {
1164 my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1165 if ($prev eq $s2) {
1166 print OUT "\t/* The following has already appeared previously */\n";
1167 print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1168 }
1169 $prev = $s2; # To warn about duplicates...
1170
3addf183 1171 (my $nn, my $vers, my $ni) = split /\\/, $nums{$s2};
62dc5aad
RL
1172 if ($v) {
1173 print OUT "\textern int $s2; /* type unknown */ /* $nn $ni */\n";
967f4ca8 1174 } else {
62dc5aad 1175 print OUT "\textern int $s2(); /* type unknown */ /* $nn $ni */\n";
967f4ca8 1176 }
12aefe78
DSH
1177 }
1178 }
1179}
1180
cc373a37
RS
1181sub get_version
1182{
3fa04f0d 1183 return $config{version};
0b352c58
RL
1184}
1185
d02b48c6 1186sub print_def_file
47339f61 1187{
948d0125 1188 (*OUT,my $name,*nums,my @symbols)=@_;
62dc5aad 1189 my $n = 1; my @e; my @r; my @v; my $prev="";
cd4c36ad 1190 my $liboptions="";
0b352c58
RL
1191 my $libname = $name;
1192 my $http_vendor = 'www.openssl.org/';
1193 my $version = get_version();
1194 my $what = "OpenSSL: implementation of Secure Socket Layer";
1195 my $description = "$what $version, $name - http://$http_vendor";
e863d920 1196 my $prevsymversion = "", $prevprevsymversion = "";
a388633d
RL
1197 # For VMS
1198 my $prevnum = 0;
fd40db9e 1199 my $symvtextcount = 0;
a388633d
RL
1200
1201 if ($W32)
1202 { $libname.="32"; }
1203 elsif ($OS2)
1204 { # DLL names should not clash on the whole system.
1205 # However, they should not have any particular relationship
1206 # to the name of the static library. Chose descriptive names
1207 # (must be at most 8 chars).
1208 my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
1209 $libname = $translate{$name} || $name;
1210 $liboptions = <<EOO;
0b352c58
RL
1211INITINSTANCE
1212DATA MULTIPLE NONSHARED
1213EOO
a388633d
RL
1214 # Vendor field can't contain colon, drat; so we omit http://
1215 $description = "\@#$http_vendor:$version#\@$what; DLL for library $name. Build for EMX -Zmtd";
1216 }
d02b48c6 1217
a388633d
RL
1218 if ($W32 || $OS2)
1219 {
1220 print OUT <<"EOF";
d02b48c6 1221;
9b3086fe 1222; Definition file for the DLL version of the $name library from OpenSSL
d02b48c6
RE
1223;
1224
0b352c58 1225LIBRARY $libname $liboptions
d02b48c6 1226
d02b48c6
RE
1227EOF
1228
e863d920 1229 print "EXPORTS\n";
a388633d
RL
1230 }
1231 elsif ($VMS)
1232 {
a388633d 1233 print OUT <<"EOF";
855eff54 1234CASE_SENSITIVE=YES
a388633d
RL
1235SYMBOL_VECTOR=(-
1236EOF
fd40db9e 1237 $symvtextcount = 16; # length of "SYMBOL_VECTOR=(-"
a388633d 1238 }
d02b48c6 1239
e863d920 1240 (@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
62dc5aad 1241 (@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
a388633d
RL
1242 if ($VMS) {
1243 # VMS needs to have the symbols on slot number order
1244 @symbols=(map { $_->[1] }
1245 sort { $a->[0] <=> $b->[0] }
1246 map { (my $s, my $i) = $_ =~ /^(.*?)\\(.*)$/;
1247 die "Error: $s doesn't have a number assigned\n"
1248 if !defined($nums{$s});
1249 (my $n, my @rest) = split /\\/, $nums{$s};
1250 [ $n, $_ ] } (@e, @r, @v));
1251 } else {
1252 @symbols=((sort @e),(sort @r), (sort @v));
1253 }
d02b48c6 1254
e863d920
MC
1255 my ($baseversion, $currversion) = get_openssl_version();
1256 my $thisversion;
1257 do {
1258 if (!defined($thisversion)) {
1259 $thisversion = $baseversion;
47339f61 1260 } else {
e863d920
MC
1261 $thisversion = get_next_version($thisversion);
1262 }
1263 foreach $sym (@symbols) {
1264 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1265 my $v = 0;
1266 $v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
1267 if (!defined($nums{$s})) {
1268 die "Error: $s does not have a number assigned\n"
1269 if(!$do_update);
1270 } else {
1271 (my $n, my $symversion, my $dummy) = split /\\/, $nums{$s};
1272 next if $symversion ne $thisversion;
1273 my %pf = ();
1274 my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1275 my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1276 if (is_valid($p,1) && is_valid($a,0)) {
1277 my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1278 if ($prev eq $s2) {
1279 print STDERR "Warning: Symbol '",$s2,
1280 "' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),
1281 ", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1282 }
1283 $prev = $s2; # To warn about duplicates...
1284 if($linux) {
1285 if ($symversion ne $prevsymversion) {
1286 if ($prevsymversion ne "") {
1287 if ($prevprevsymversion ne "") {
1288 print OUT "} OPENSSL_"
1289 ."$prevprevsymversion;\n\n";
1290 } else {
1291 print OUT "};\n\n";
1292 }
1293 }
1294 print OUT "OPENSSL_$symversion {\n global:\n";
1295 $prevprevsymversion = $prevsymversion;
1296 $prevsymversion = $symversion;
1297 }
1298 print OUT " $s2;\n";
a388633d
RL
1299 } elsif ($VMS) {
1300 while(++$prevnum < $n) {
e84193e4
RL
1301 my $symline=" ,SPARE -\n ,SPARE -\n";
1302 if ($symvtextcount + length($symline) - 2 > 1024) {
a388633d 1303 print OUT ")\nSYMBOL_VECTOR=(-\n";
fd40db9e 1304 $symvtextcount = 16; # length of "SYMBOL_VECTOR=(-"
a388633d 1305 }
e84193e4
RL
1306 if ($symvtextcount == 16) {
1307 # Take away first comma
1308 $symline =~ s/,//;
fd40db9e 1309 }
e84193e4
RL
1310 print OUT $symline;
1311 $symvtextcount += length($symline) - 2;
a388633d
RL
1312 }
1313 (my $s_uc = $s) =~ tr/a-z/A-Z/;
d9aad55a
RL
1314 my $symtype=
1315 $v ? "DATA" : "PROCEDURE";
1316 my $symline=
1317 ($s_uc ne $s
e84193e4
RL
1318 ? " ,$s_uc/$s=$symtype -\n ,$s=$symtype -\n"
1319 : " ,$s=$symtype -\n ,SPARE -\n");
1320 if ($symvtextcount + length($symline) - 2 > 1024) {
a388633d 1321 print OUT ")\nSYMBOL_VECTOR=(-\n";
fd40db9e 1322 $symvtextcount = 16; # length of "SYMBOL_VECTOR=(-"
a388633d 1323 }
e84193e4
RL
1324 if ($symvtextcount == 16) {
1325 # Take away first comma
1326 $symline =~ s/,//;
fd40db9e 1327 }
e84193e4
RL
1328 print OUT $symline;
1329 $symvtextcount += length($symline) - 2;
e863d920
MC
1330 } elsif($v && !$OS2) {
1331 printf OUT " %s%-39s @%-8d DATA\n",
1332 ($W32)?"":"_",$s2,$n;
1333 } else {
1334 printf OUT " %s%-39s @%d\n",
1335 ($W32||$OS2)?"":"_",$s2,$n;
1336 }
9c67ab2f 1337 }
965c1775 1338 }
d02b48c6 1339 }
e863d920
MC
1340 } while ($thisversion ne $currversion);
1341 if ($linux) {
1342 if ($prevprevsymversion ne "") {
1343 print OUT " local: *;\n} OPENSSL_$prevprevsymversion;\n\n";
1344 } else {
1345 print OUT " local: *;\n};\n\n";
1346 }
a388633d
RL
1347 } elsif ($VMS) {
1348 print OUT ")\n";
1349 (my $libvmaj, my $libvmin, my $libvedit) =
1350 $currversion =~ /^(\d+)_(\d+)_(\d+)$/;
1351 # The reason to multiply the edit number with 100 is to make space
1352 # for the possibility that we want to encode the patch letters
1353 print OUT "GSMATCH=LEQUAL,",($libvmaj * 100 + $libvmin),",",($libvedit * 100),"\n";
1354 }
47339f61
DSH
1355 printf OUT "\n";
1356}
d02b48c6
RE
1357
1358sub load_numbers
47339f61
DSH
1359{
1360 my($name)=@_;
1361 my(@a,%ret);
e863d920 1362 my $prevversion;
d02b48c6 1363
55a9cc6e 1364 $max_num = 0;
948d0125
RL
1365 $num_noinfo = 0;
1366 $prev = "";
62dc5aad 1367 $prev_cnt = 0;
55a9cc6e 1368
e863d920
MC
1369 my ($baseversion, $currversion) = get_openssl_version();
1370
d02b48c6 1371 open(IN,"<$name") || die "unable to open $name:$!\n";
47339f61 1372 while (<IN>) {
9ba96fbb 1373 s|\R$||; # Better chomp
d02b48c6
RE
1374 s/#.*$//;
1375 next if /^\s*$/;
1376 @a=split;
948d0125 1377 if (defined $ret{$a[0]}) {
62dc5aad
RL
1378 # This is actually perfectly OK
1379 #print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n";
948d0125
RL
1380 }
1381 if ($max_num > $a[1]) {
1382 print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n";
1383 }
62dc5aad 1384 elsif ($max_num == $a[1]) {
948d0125
RL
1385 # This is actually perfectly OK
1386 #print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n";
62dc5aad
RL
1387 if ($a[0] eq $prev) {
1388 $prev_cnt++;
1389 $a[0] .= "{$prev_cnt}";
1390 }
1391 }
1392 else {
1393 $prev_cnt = 0;
948d0125
RL
1394 }
1395 if ($#a < 2) {
1396 # Existence will be proven later, in do_defs
1397 $ret{$a[0]}=$a[1];
1398 $num_noinfo++;
1399 } else {
e863d920
MC
1400 #Sanity check the version number
1401 if (defined $prevversion) {
1402 check_version_lte($prevversion, $a[2]);
1403 }
1404 check_version_lte($a[2], $currversion);
1405 $prevversion = $a[2];
1406 $ret{$a[0]}=$a[1]."\\".$a[2]."\\".$a[3]; # \\ is a special marker
948d0125 1407 }
55a9cc6e 1408 $max_num = $a[1] if $a[1] > $max_num;
948d0125
RL
1409 $prev=$a[0];
1410 }
1411 if ($num_noinfo) {
1412 print STDERR "Warning: $num_noinfo symbols were without info.";
1413 if ($do_rewrite) {
1414 printf STDERR " The rewrite will fix this.\n";
1415 } else {
1416 printf STDERR " You should do a rewrite to fix this.\n";
1417 }
47339f61 1418 }
d02b48c6
RE
1419 close(IN);
1420 return(%ret);
47339f61 1421}
55a9cc6e 1422
948d0125
RL
1423sub parse_number
1424{
1425 (my $str, my $what) = @_;
3addf183 1426 (my $n, my $v, my $i) = split(/\\/,$str);
948d0125
RL
1427 if ($what eq "n") {
1428 return $n;
1429 } else {
1430 return $i;
1431 }
1432}
1433
1434sub rewrite_numbers
1435{
1436 (*OUT,$name,*nums,@symbols)=@_;
1437 my $thing;
1438
62dc5aad 1439 my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
948d0125
RL
1440 my $r; my %r; my %rsyms;
1441 foreach $r (@r) {
1442 (my $s, my $i) = split /\\/, $r;
1443 my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1444 $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1445 $r{$a} = $s."\\".$i;
1446 $rsyms{$s} = 1;
1447 }
1448
451e60e9
RL
1449 my %syms = ();
1450 foreach $_ (@symbols) {
1451 (my $n, my $i) = split /\\/;
1452 $syms{$n} = 1;
1453 }
1454
89eeccac
RL
1455 my @s=sort {
1456 &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n")
1457 || $a cmp $b
1458 } keys %nums;
948d0125 1459 foreach $sym (@s) {
3addf183 1460 (my $n, my $vers, my $i) = split /\\/, $nums{$sym};
948d0125
RL
1461 next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/;
1462 next if defined($rsyms{$sym});
62dc5aad 1463 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
1464 $i="NOEXIST::FUNCTION:"
1465 if !defined($i) || $i eq "" || !defined($syms{$sym});
62dc5aad
RL
1466 my $s2 = $sym;
1467 $s2 =~ s/\{[0-9]+\}$//;
3addf183 1468 printf OUT "%s%-39s %d\t%s\t%s\n","",$s2,$n,$vers,$i;
948d0125
RL
1469 if (exists $r{$sym}) {
1470 (my $s, $i) = split /\\/,$r{$sym};
62dc5aad
RL
1471 my $s2 = $s;
1472 $s2 =~ s/\{[0-9]+\}$//;
3addf183 1473 printf OUT "%s%-39s %d\t%s\t%s\n","",$s2,$n,$vers,$i;
948d0125
RL
1474 }
1475 }
1476}
1477
55a9cc6e 1478sub update_numbers
47339f61 1479{
948d0125
RL
1480 (*OUT,$name,*nums,my $start_num, my @symbols)=@_;
1481 my $new_syms = 0;
3addf183
MC
1482 my $basevers;
1483 my $vers;
1484
1485 ($basevers, $vers) = get_openssl_version();
948d0125 1486
62dc5aad 1487 my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
948d0125
RL
1488 my $r; my %r; my %rsyms;
1489 foreach $r (@r) {
1490 (my $s, my $i) = split /\\/, $r;
1491 my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1492 $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1493 $r{$a} = $s."\\".$i;
1494 $rsyms{$s} = 1;
1495 }
1496
1497 foreach $sym (@symbols) {
1498 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1499 next if $i =~ /^.*?:.*?:\w+\(\w+\)/;
1500 next if defined($rsyms{$sym});
1501 die "ERROR: Symbol $sym had no info attached to it."
1502 if $i eq "";
1503 if (!exists $nums{$s}) {
1504 $new_syms++;
62dc5aad
RL
1505 my $s2 = $s;
1506 $s2 =~ s/\{[0-9]+\}$//;
3addf183 1507 printf OUT "%s%-39s %d\t%s\t%s\n","",$s2, ++$start_num,$vers,$i;
948d0125 1508 if (exists $r{$s}) {
33b1a4c2 1509 ($s, $i) = split /\\/,$r{$s};
62dc5aad 1510 $s =~ s/\{[0-9]+\}$//;
3addf183 1511 printf OUT "%s%-39s %d\t%s\t%s\n","",$s, $start_num,$vers,$i;
948d0125 1512 }
55a9cc6e 1513 }
47339f61 1514 }
948d0125 1515 if($new_syms) {
cc373a37 1516 print STDERR "$name: Added $new_syms new symbols\n";
55a9cc6e 1517 } else {
cc373a37 1518 print STDERR "$name: No new symbols added\n";
948d0125
RL
1519 }
1520}
1521
1522sub check_existing
1523{
1524 (*nums, my @symbols)=@_;
1525 my %existing; my @remaining;
1526 @remaining=();
1527 foreach $sym (@symbols) {
1528 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1529 $existing{$s}=1;
1530 }
1531 foreach $sym (keys %nums) {
1532 if (!exists $existing{$sym}) {
1533 push @remaining, $sym;
1534 }
1535 }
1536 if(@remaining) {
1537 print STDERR "The following symbols do not seem to exist:\n";
1538 foreach $sym (@remaining) {
1539 print STDERR "\t",$sym,"\n";
1540 }
55a9cc6e 1541 }
47339f61 1542}
948d0125 1543
07c4c14c
MC
1544sub count_parens
1545{
1546 my $line = shift(@_);
1547
1548 my $open = $line =~ tr/\(//;
1549 my $close = $line =~ tr/\)//;
1550
1551 return $open - $close;
1552}
1553
e863d920
MC
1554#Parse opensslv.h to get the current version number. Also work out the base
1555#version, i.e. the lowest version number that is binary compatible with this
1556#version
1557sub get_openssl_version()
1558{
d7465918
RL
1559 my $fn = catfile($config{sourcedir},"include","openssl","opensslv.h");
1560 open (IN, "$fn") || die "Can't open opensslv.h";
e863d920
MC
1561
1562 while(<IN>) {
1563 if (/OPENSSL_VERSION_TEXT\s+"OpenSSL (\d\.\d\.)(\d[a-z]*)(-| )/) {
1564 my $suffix = $2;
56afc187 1565 (my $baseversion = $1) =~ s/\./_/g;
e863d920
MC
1566 close IN;
1567 return ($baseversion."0", $baseversion.$suffix);
1568 }
1569 }
1570 die "Can't find OpenSSL version number\n";
1571}
1572
1573#Given an OpenSSL version number, calculate the next version number. If the
1574#version number gets to a.b.czz then we go to a.b.(c+1)
1575sub get_next_version()
1576{
1577 my $thisversion = shift;
1578
1579 my ($base, $letter) = $thisversion =~ /^(\d_\d_\d)([a-z]{0,2})$/;
1580
1581 if ($letter eq "zz") {
1582 my $lastnum = substr($base, -1);
1583 return substr($base, 0, length($base)-1).(++$lastnum);
1584 }
1585 return $base.get_next_letter($letter);
1586}
1587
1588#Given the letters off the end of an OpenSSL version string, calculate what
1589#the letters for the next release would be.
1590sub get_next_letter()
1591{
1592 my $thisletter = shift;
1593 my $baseletter = "";
1594 my $endletter;
1595
1596 if ($thisletter eq "") {
1597 return "a";
1598 }
1599 if ((length $thisletter) > 1) {
1600 ($baseletter, $endletter) = $thisletter =~ /([a-z]+)([a-z])/;
1601 } else {
1602 $endletter = $thisletter;
1603 }
1604
1605 if ($endletter eq "z") {
1606 return $thisletter."a";
1607 } else {
1608 return $baseletter.(++$endletter);
1609 }
1610}
1611
1612#Check if a version is less than or equal to the current version. Its a fatal
1613#error if not. They must also only differ in letters, or the last number (i.e.
1614#the first two numbers must be the same)
1615sub check_version_lte()
1616{
1617 my ($testversion, $currversion) = @_;
1618 my $lentv;
1619 my $lencv;
1620 my $cvbase;
1621
1622 my ($cvnums) = $currversion =~ /^(\d_\d_\d)[a-z]*$/;
1623 my ($tvnums) = $testversion =~ /^(\d_\d_\d)[a-z]*$/;
1624
1625 #Die if we can't parse the version numbers or they don't look sane
1626 die "Invalid version number: $testversion and $currversion\n"
1627 if (!defined($cvnums) || !defined($tvnums)
1628 || length($cvnums) != 5
1629 || length($tvnums) != 5);
1630
1631 #If the base versions (without letters) don't match check they only differ
1632 #in the last number
1633 if ($cvnums ne $tvnums) {
1634 die "Invalid version number: $testversion "
1635 ."for current version $currversion\n"
1636 if (substr($cvnums, -1) < substr($tvnums, -1)
1637 || substr($cvnums, 0, 4) ne substr($tvnums, 0, 4));
1638 return;
1639 }
1640 #If we get here then the base version (i.e. the numbers) are the same - they
1641 #only differ in the letters
1642
1643 $lentv = length $testversion;
1644 $lencv = length $currversion;
1645
1646 #If the testversion has more letters than the current version then it must
1647 #be later (or malformed)
1648 if ($lentv > $lencv) {
1649 die "Invalid version number: $testversion "
1650 ."is greater than $currversion\n";
1651 }
1652
1653 #Get the last letter from the current version
1654 my ($cvletter) = $currversion =~ /([a-z])$/;
1655 if (defined $cvletter) {
1656 ($cvbase) = $currversion =~ /(\d_\d_\d[a-z]*)$cvletter$/;
1657 } else {
1658 $cvbase = $currversion;
1659 }
1660 die "Unable to parse version number $currversion" if (!defined $cvbase);
1661 my $tvbase;
1662 my ($tvletter) = $testversion =~ /([a-z])$/;
1663 if (defined $tvletter) {
1664 ($tvbase) = $testversion =~ /(\d_\d_\d[a-z]*)$tvletter$/;
1665 } else {
1666 $tvbase = $testversion;
1667 }
1668 die "Unable to parse version number $testversion" if (!defined $tvbase);
1669
1670 if ($lencv > $lentv) {
1671 #If current version has more letters than testversion then testversion
1672 #minus the final letter must be a substring of the current version
1673 die "Invalid version number $testversion "
1674 ."is greater than $currversion or is invalid\n"
1675 if (index($cvbase, $tvbase) != 0);
1676 } else {
1677 #If both versions have the same number of letters then they must be
1678 #equal up to the last letter, and the last letter in testversion must
1679 #be less than or equal to the last letter in current version.
1680 die "Invalid version number $testversion "
1681 ."is greater than $currversion\n"
1682 if (($cvbase ne $tvbase) && ($tvletter gt $cvletter));
1683 }
1684}
7a556fb6
DSH
1685
1686sub do_deprecated()
1687{
1688 my ($decl, $plats, $algs) = @_;
ca0004e5
VD
1689 $decl =~ /^\s*(DEPRECATEDIN_\d+_\d+_\d+)\s*\((.*)\)\s*$/
1690 or die "Bad DEPRECTEDIN: $decl\n";
7a556fb6
DSH
1691 my $info1 .= "#INFO:";
1692 $info1 .= join(',', @{$plats}) . ":";
1693 my $info2 = $info1;
1694 $info1 .= join(',',@{$algs}, $1) . ";";
1695 $info2 .= join(',',@{$algs}) . ";";
1696 return $info1 . $2 . ";" . $info2;
1697}