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