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