]> git.ipfire.org Git - thirdparty/openssl.git/blame - util/mkdef.pl
Add SRP support.
[thirdparty/openssl.git] / util / mkdef.pl
CommitLineData
ce9449cf 1#!/usr/local/bin/perl -w
d02b48c6
RE
2#
3# generate a .def file
4#
5# It does this by parsing the header files and looking for the
47339f61 6# prototyped functions: it then prunes the output.
d02b48c6 7#
948d0125
RL
8# Intermediary files are created, call libeay.num and ssleay.num,...
9# Previously, they had the following format:
10#
11# routine-name nnnn
12#
13# But that isn't enough for a number of reasons, the first on being that
14# this format is (needlessly) very Win32-centric, and even then...
15# One of the biggest problems is that there's no information about what
16# routines should actually be used, which varies with what crypto algorithms
17# are disabled. Also, some operating systems (for example VMS with VAX C)
18# need to keep track of the global variables as well as the functions.
19#
20# So, a remake of this script is done so as to include information on the
21# kind of symbol it is (function or variable) and what algorithms they're
22# part of. This will allow easy translating to .def files or the corresponding
23# file in other operating systems (a .opt file for VMS, possibly with a .mar
24# file).
25#
26# The format now becomes:
27#
28# routine-name nnnn info
29#
30# and the "info" part is actually a colon-separated string of fields with
31# the following meaning:
32#
33# existence:platform:kind:algorithms
34#
35# - "existence" can be "EXIST" or "NOEXIST" depending on if the symbol is
36# found somewhere in the source,
37# - "platforms" is empty if it exists on all platforms, otherwise it contains
38# comma-separated list of the platform, just as they are if the symbol exists
39# for those platforms, or prepended with a "!" if not. This helps resolve
62dc5aad 40# symbol name variants for platforms where the names are too long for the
948d0125 41# compiler or linker, or if the systems is case insensitive and there is a
62dc5aad
RL
42# clash, or the symbol is implemented differently (see
43# EXPORT_VAR_AS_FUNCTION). This script assumes renaming of symbols is found
44# in the file crypto/symhacks.h.
45# The semantics for the platforms is that every item is checked against the
5012158a
LJ
46# environment. For the negative items ("!FOO"), if any of them is false
47# (i.e. "FOO" is true) in the environment, the corresponding symbol can't be
62dc5aad
RL
48# used. For the positive itms, if all of them are false in the environment,
49# the corresponding symbol can't be used. Any combination of positive and
50# negative items are possible, and of course leave room for some redundancy.
948d0125
RL
51# - "kind" is "FUNCTION" or "VARIABLE". The meaning of that is obvious.
52# - "algorithms" is a comma-separated list of algorithm names. This helps
53# exclude symbols that are part of an algorithm that some user wants to
54# exclude.
55#
d02b48c6 56
d399fdf8
RL
57my $debug=0;
58
948d0125
RL
59my $crypto_num= "util/libeay.num";
60my $ssl_num= "util/ssleay.num";
cd4c36ad 61my $libname;
d02b48c6 62
47339f61 63my $do_update = 0;
1449bda0 64my $do_rewrite = 1;
47339f61
DSH
65my $do_crypto = 0;
66my $do_ssl = 0;
0f583f69 67my $do_ctest = 0;
967f4ca8 68my $do_ctestall = 0;
c47c6196 69my $do_checkexist = 0;
47339f61 70
62dc5aad 71my $VMSVAX=0;
af55c09d 72my $VMSNonVAX=0;
948d0125
RL
73my $VMS=0;
74my $W32=0;
75my $W16=0;
0f583f69 76my $NT=0;
cd4c36ad 77my $OS2=0;
28a98809 78# Set this to make typesafe STACK definitions appear in DEF
e41c8d6a 79my $safe_stack_def = 0;
31ff97b2 80
62dc5aad 81my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
53f76337 82 "EXPORT_VAR_AS_FUNCTION", "ZLIB", "OPENSSL_FIPS" );
cd4c36ad 83my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
948d0125 84my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
3f07fe09 85 "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
665560e9 86 "SHA256", "SHA512", "RIPEMD",
36246be9 87 "MDC2", "WHIRLPOOL", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "EC2M",
96afc1cf 88 "HMAC", "AES", "CAMELLIA", "SEED", "GOST",
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"
64387788 95 "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
6cb68620 96 # Engines
987bebaf 97 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
d137b56a
DSH
98 # RFC3779
99 "RFC3779",
c20276e4 100 # TLS
edc032b5 101 "TLSEXT", "PSK", "SRP",
8931b30d
DSH
102 # CMS
103 "CMS",
d8bd55a3
DSH
104 # CryptoAPI Engine
105 "CAPIENG",
06ddf8eb
DSH
106 # SSL v2
107 "SSL2",
79bd20fd
DSH
108 # JPAKE
109 "JPAKE",
36246be9
DSH
110 # NEXTPROTONEG
111 "NEXTPROTONEG",
4ccfe5f4
RL
112 # Deprecated functions
113 "DEPRECATED" );
948d0125 114
0f583f69 115my $options="";
52272327 116open(IN,"<Makefile") || die "unable to open Makefile!\n";
31ff97b2
UM
117while(<IN>) {
118 $options=$1 if (/^OPTIONS=(.*)$/);
119}
ce457a54 120close(IN);
31ff97b2 121
0f583f69
UM
122# The following ciphers may be excluded (by Configure). This means functions
123# defined with ifndef(NO_XXX) are not included in the .def file, and everything
124# in directory xxx is ignored.
125my $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
96afc1cf 126my $no_cast; my $no_whirlpool; my $no_camellia; my $no_seed;
3009458e 127my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
c063f2c5 128my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
5cd48abf 129my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
f858d222 130my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
d8bd55a3 131my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
36246be9 132my $no_jpake; my $no_ssl2; my $no_ec2m; my $no_nextprotoneg;
edc032b5 133my $no_srp;
8931b30d 134
53f76337
DSH
135my $fips;
136
8931b30d 137my $zlib;
987bebaf 138
0f583f69 139
31ff97b2 140foreach (@ARGV, split(/ /, $options))
d02b48c6 141 {
62dc5aad 142 $debug=1 if $_ eq "debug";
06c68491 143 $W32=1 if $_ eq "32";
948d0125 144 $W16=1 if $_ eq "16";
06c68491
DSH
145 if($_ eq "NT") {
146 $W32 = 1;
147 $NT = 1;
148 }
62dc5aad
RL
149 if ($_ eq "VMS-VAX") {
150 $VMS=1;
151 $VMSVAX=1;
152 }
af55c09d 153 if ($_ eq "VMS-NonVAX") {
62dc5aad 154 $VMS=1;
af55c09d 155 $VMSNonVAX=1;
62dc5aad 156 }
948d0125 157 $VMS=1 if $_ eq "VMS";
cd4c36ad 158 $OS2=1 if $_ eq "OS2";
53f76337 159 $fips=1 if /^fips/;
b2cf7c64 160 if ($_ eq "zlib" || $_ eq "enable-zlib" || $_ eq "zlib-dynamic"
8931b30d
DSH
161 || $_ eq "enable-zlib-dynamic") {
162 $zlib = 1;
163 }
164
d02b48c6 165 $do_ssl=1 if $_ eq "ssleay";
cd4c36ad
RL
166 if ($_ eq "ssl") {
167 $do_ssl=1;
168 $libname=$_
169 }
d02b48c6 170 $do_crypto=1 if $_ eq "libeay";
cd4c36ad
RL
171 if ($_ eq "crypto") {
172 $do_crypto=1;
173 $libname=$_;
174 }
fbf002bb
DSH
175 $no_static_engine=1 if $_ eq "no-static-engine";
176 $no_static_engine=0 if $_ eq "enable-static-engine";
55a9cc6e 177 $do_update=1 if $_ eq "update";
948d0125 178 $do_rewrite=1 if $_ eq "rewrite";
12aefe78 179 $do_ctest=1 if $_ eq "ctest";
967f4ca8 180 $do_ctestall=1 if $_ eq "ctestall";
c47c6196 181 $do_checkexist=1 if $_ eq "exist";
a8b07aa4 182 #$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK";
8cf65228
UM
183
184 if (/^no-rc2$/) { $no_rc2=1; }
185 elsif (/^no-rc4$/) { $no_rc4=1; }
186 elsif (/^no-rc5$/) { $no_rc5=1; }
187 elsif (/^no-idea$/) { $no_idea=1; }
be054868 188 elsif (/^no-des$/) { $no_des=1; $no_mdc2=1; }
8cf65228
UM
189 elsif (/^no-bf$/) { $no_bf=1; }
190 elsif (/^no-cast$/) { $no_cast=1; }
ec645d90 191 elsif (/^no-whirlpool$/) { $no_whirlpool=1; }
8cf65228 192 elsif (/^no-md2$/) { $no_md2=1; }
3009458e 193 elsif (/^no-md4$/) { $no_md4=1; }
8cf65228
UM
194 elsif (/^no-md5$/) { $no_md5=1; }
195 elsif (/^no-sha$/) { $no_sha=1; }
196 elsif (/^no-ripemd$/) { $no_ripemd=1; }
197 elsif (/^no-mdc2$/) { $no_mdc2=1; }
198 elsif (/^no-rsa$/) { $no_rsa=1; }
199 elsif (/^no-dsa$/) { $no_dsa=1; }
200 elsif (/^no-dh$/) { $no_dh=1; }
b4f682d3 201 elsif (/^no-ec$/) { $no_ec=1; }
4d94ae00 202 elsif (/^no-ecdsa$/) { $no_ecdsa=1; }
e172d60d 203 elsif (/^no-ecdh$/) { $no_ecdh=1; }
8cf65228 204 elsif (/^no-hmac$/) { $no_hmac=1; }
c47c6196 205 elsif (/^no-aes$/) { $no_aes=1; }
f3dea9a5 206 elsif (/^no-camellia$/) { $no_camellia=1; }
96afc1cf 207 elsif (/^no-seed$/) { $no_seed=1; }
3f07fe09
RL
208 elsif (/^no-evp$/) { $no_evp=1; }
209 elsif (/^no-lhash$/) { $no_lhash=1; }
210 elsif (/^no-stack$/) { $no_stack=1; }
211 elsif (/^no-err$/) { $no_err=1; }
212 elsif (/^no-buffer$/) { $no_buffer=1; }
213 elsif (/^no-bio$/) { $no_bio=1; }
214 #elsif (/^no-locking$/) { $no_locking=1; }
215 elsif (/^no-comp$/) { $no_comp=1; }
216 elsif (/^no-dso$/) { $no_dso=1; }
c063f2c5 217 elsif (/^no-krb5$/) { $no_krb5=1; }
0b13e9f0 218 elsif (/^no-engine$/) { $no_engine=1; }
5cd48abf 219 elsif (/^no-hw$/) { $no_hw=1; }
987bebaf 220 elsif (/^no-gmp$/) { $no_gmp=1; }
d137b56a 221 elsif (/^no-rfc3779$/) { $no_rfc3779=1; }
525de5d3 222 elsif (/^no-tlsext$/) { $no_tlsext=1; }
8931b30d 223 elsif (/^no-cms$/) { $no_cms=1; }
36246be9
DSH
224 elsif (/^no-ec2m$/) { $no_ec2m=1; }
225 elsif (/^no-nextprotoneg$/) { $no_nextprotoneg=1; }
06ddf8eb 226 elsif (/^no-ssl2$/) { $no_ssl2=1; }
d8bd55a3 227 elsif (/^no-capieng$/) { $no_capieng=1; }
79bd20fd 228 elsif (/^no-jpake$/) { $no_jpake=1; }
edc032b5 229 elsif (/^no-srp$/) { $no_srp=1; }
d02b48c6
RE
230 }
231
12aefe78 232
cd4c36ad
RL
233if (!$libname) {
234 if ($do_ssl) {
235 $libname="SSLEAY";
236 }
237 if ($do_crypto) {
238 $libname="LIBEAY";
239 }
240}
241
948d0125 242# If no platform is given, assume WIN32
cd4c36ad 243if ($W32 + $W16 + $VMS + $OS2 == 0) {
948d0125
RL
244 $W32 = 1;
245}
246
247# Add extra knowledge
248if ($W16) {
249 $no_fp_api=1;
250}
251
d02b48c6
RE
252if (!$do_ssl && !$do_crypto)
253 {
cd4c36ad 254 print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT | OS2 ]\n";
d02b48c6
RE
255 exit(1);
256 }
257
258%ssl_list=&load_numbers($ssl_num);
55a9cc6e 259$max_ssl = $max_num;
d02b48c6 260%crypto_list=&load_numbers($crypto_num);
55a9cc6e 261$max_crypto = $max_num;
d02b48c6 262
0f583f69 263my $ssl="ssl/ssl.h";
3f07fe09 264$ssl.=" ssl/kssl.h";
c20276e4 265$ssl.=" ssl/tls1.h";
d02b48c6 266
0f583f69 267my $crypto ="crypto/crypto.h";
6ac15712 268$crypto.=" crypto/o_dir.h";
c2e4f17c 269$crypto.=" crypto/des/des.h crypto/des/des_old.h" ; # unless $no_des;
0d96bf89
RL
270$crypto.=" crypto/idea/idea.h" ; # unless $no_idea;
271$crypto.=" crypto/rc4/rc4.h" ; # unless $no_rc4;
272$crypto.=" crypto/rc5/rc5.h" ; # unless $no_rc5;
273$crypto.=" crypto/rc2/rc2.h" ; # unless $no_rc2;
274$crypto.=" crypto/bf/blowfish.h" ; # unless $no_bf;
275$crypto.=" crypto/cast/cast.h" ; # unless $no_cast;
ec645d90 276$crypto.=" crypto/whrlpool/whrlpool.h" ;
0d96bf89
RL
277$crypto.=" crypto/md2/md2.h" ; # unless $no_md2;
278$crypto.=" crypto/md4/md4.h" ; # unless $no_md4;
279$crypto.=" crypto/md5/md5.h" ; # unless $no_md5;
280$crypto.=" crypto/mdc2/mdc2.h" ; # unless $no_mdc2;
281$crypto.=" crypto/sha/sha.h" ; # unless $no_sha;
282$crypto.=" crypto/ripemd/ripemd.h" ; # unless $no_ripemd;
6f9079fd 283$crypto.=" crypto/aes/aes.h" ; # unless $no_aes;
f3dea9a5 284$crypto.=" crypto/camellia/camellia.h" ; # unless $no_camellia;
96afc1cf 285$crypto.=" crypto/seed/seed.h"; # unless $no_seed;
d02b48c6
RE
286
287$crypto.=" crypto/bn/bn.h";
0d96bf89
RL
288$crypto.=" crypto/rsa/rsa.h" ; # unless $no_rsa;
289$crypto.=" crypto/dsa/dsa.h" ; # unless $no_dsa;
290$crypto.=" crypto/dh/dh.h" ; # unless $no_dh;
291$crypto.=" crypto/ec/ec.h" ; # unless $no_ec;
4d94ae00 292$crypto.=" crypto/ecdsa/ecdsa.h" ; # unless $no_ecdsa;
e172d60d 293$crypto.=" crypto/ecdh/ecdh.h" ; # unless $no_ecdh;
0d96bf89 294$crypto.=" crypto/hmac/hmac.h" ; # unless $no_hmac;
d02b48c6 295
0b13e9f0 296$crypto.=" crypto/engine/engine.h"; # unless $no_engine;
0d96bf89
RL
297$crypto.=" crypto/stack/stack.h" ; # unless $no_stack;
298$crypto.=" crypto/buffer/buffer.h" ; # unless $no_buffer;
299$crypto.=" crypto/bio/bio.h" ; # unless $no_bio;
300$crypto.=" crypto/dso/dso.h" ; # unless $no_dso;
301$crypto.=" crypto/lhash/lhash.h" ; # unless $no_lhash;
d02b48c6
RE
302$crypto.=" crypto/conf/conf.h";
303$crypto.=" crypto/txt_db/txt_db.h";
304
0d96bf89 305$crypto.=" crypto/evp/evp.h" ; # unless $no_evp;
d02b48c6
RE
306$crypto.=" crypto/objects/objects.h";
307$crypto.=" crypto/pem/pem.h";
308#$crypto.=" crypto/meth/meth.h";
309$crypto.=" crypto/asn1/asn1.h";
9c67ab2f 310$crypto.=" crypto/asn1/asn1t.h";
d02b48c6 311$crypto.=" crypto/asn1/asn1_mac.h";
0d96bf89 312$crypto.=" crypto/err/err.h" ; # unless $no_err;
d02b48c6 313$crypto.=" crypto/pkcs7/pkcs7.h";
ee0508d4 314$crypto.=" crypto/pkcs12/pkcs12.h";
d02b48c6
RE
315$crypto.=" crypto/x509/x509.h";
316$crypto.=" crypto/x509/x509_vfy.h";
679ab7c3 317$crypto.=" crypto/x509v3/x509v3.h";
c7235be6 318$crypto.=" crypto/ts/ts.h";
d02b48c6 319$crypto.=" crypto/rand/rand.h";
0d96bf89 320$crypto.=" crypto/comp/comp.h" ; # unless $no_comp;
eb64730b 321$crypto.=" crypto/ocsp/ocsp.h";
1449bda0 322$crypto.=" crypto/ui/ui.h crypto/ui/ui_compat.h";
c62da732 323$crypto.=" crypto/krb5/krb5_asn.h";
863d447e 324#$crypto.=" crypto/store/store.h";
6c61726b 325$crypto.=" crypto/pqueue/pqueue.h";
8931b30d 326$crypto.=" crypto/cms/cms.h";
ab7e09f5 327$crypto.=" crypto/jpake/jpake.h";
edc032b5 328$crypto.=" crypto/srp/srp.h";
18f3385d 329$crypto.=" crypto/modes/modes.h";
53f76337 330$crypto.=" fips/fips.h fips/rand/fips_rand.h";
d02b48c6 331
948d0125 332my $symhacks="crypto/symhacks.h";
55a9cc6e 333
948d0125
RL
334my @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks);
335my @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks);
47339f61 336
55a9cc6e
DSH
337if ($do_update) {
338
339if ($do_ssl == 1) {
948d0125
RL
340
341 &maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols);
342 if ($do_rewrite == 1) {
343 open(OUT, ">$ssl_num");
344 &rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols);
948d0125
RL
345 } else {
346 open(OUT, ">>$ssl_num");
347 }
348 &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols);
55a9cc6e
DSH
349 close OUT;
350}
351
352if($do_crypto == 1) {
948d0125
RL
353
354 &maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols);
355 if ($do_rewrite == 1) {
356 open(OUT, ">$crypto_num");
357 &rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols);
358 } else {
359 open(OUT, ">>$crypto_num");
360 }
361 &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols);
55a9cc6e 362 close OUT;
12aefe78
DSH
363}
364
c47c6196
DSH
365} elsif ($do_checkexist) {
366 &check_existing(*ssl_list, @ssl_symbols)
367 if $do_ssl == 1;
368 &check_existing(*crypto_list, @crypto_symbols)
369 if $do_crypto == 1;
967f4ca8 370} elsif ($do_ctest || $do_ctestall) {
12aefe78
DSH
371
372 print <<"EOF";
373
374/* Test file to check all DEF file symbols are present by trying
375 * to link to all of them. This is *not* intended to be run!
376 */
377
378int main()
379{
380EOF
948d0125 381 &print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols)
12aefe78
DSH
382 if $do_ssl == 1;
383
948d0125 384 &print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols)
12aefe78
DSH
385 if $do_crypto == 1;
386
387 print "}\n";
55a9cc6e
DSH
388
389} else {
8cf65228 390
cd4c36ad 391 &print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
55a9cc6e
DSH
392 if $do_ssl == 1;
393
cd4c36ad 394 &print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
55a9cc6e 395 if $do_crypto == 1;
8cf65228 396
55a9cc6e 397}
d02b48c6 398
d02b48c6
RE
399
400sub do_defs
47339f61 401{
948d0125 402 my($name,$files,$symhacksfile)=@_;
0f583f69 403 my $file;
47339f61 404 my @ret;
948d0125
RL
405 my %syms;
406 my %platform; # For anything undefined, we assume ""
407 my %kind; # For anything undefined, we assume "FUNCTION"
408 my %algorithm; # For anything undefined, we assume ""
62dc5aad
RL
409 my %variant;
410 my %variant_cnt; # To be able to allocate "name{n}" if "name"
411 # is the same name as the original.
0f583f69 412 my $cpp;
3f07fe09 413 my %unknown_algorithms = ();
d02b48c6 414
948d0125 415 foreach $file (split(/\s+/,$symhacksfile." ".$files))
d02b48c6 416 {
89eeccac 417 print STDERR "DEBUG: starting on $file:\n" if $debug;
d02b48c6 418 open(IN,"<$file") || die "unable to open $file:$!\n";
0f583f69 419 my $line = "", my $def= "";
47339f61 420 my %tag = (
d399fdf8
RL
421 (map { $_ => 0 } @known_platforms),
422 (map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
cf1b7d96 423 (map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
47339f61 424 NOPROTO => 0,
47339f61
DSH
425 PERL5 => 0,
426 _WINDLL => 0,
47339f61
DSH
427 CONST_STRICT => 0,
428 TRUE => 1,
429 );
948d0125 430 my $symhacking = $file eq $symhacksfile;
267a1927
RL
431 my @current_platforms = ();
432 my @current_algorithms = ();
433
62dc5aad
RL
434 # params: symbol, alias, platforms, kind
435 # The reason to put this subroutine in a variable is that
436 # it will otherwise create it's own, unshared, version of
437 # %tag and %variant...
438 my $make_variant = sub
439 {
440 my ($s, $a, $p, $k) = @_;
441 my ($a1, $a2);
442
443 print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
444 if (defined($p))
445 {
446 $a1 = join(",",$p,
447 grep(!/^$/,
448 map { $tag{$_} == 1 ? $_ : "" }
449 @known_platforms));
450 }
451 else
452 {
453 $a1 = join(",",
454 grep(!/^$/,
455 map { $tag{$_} == 1 ? $_ : "" }
456 @known_platforms));
457 }
458 $a2 = join(",",
459 grep(!/^$/,
460 map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
461 @known_ossl_platforms));
462 print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
463 if ($a1 eq "") { $a1 = $a2; }
464 elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
465 if ($a eq $s)
466 {
467 if (!defined($variant_cnt{$s}))
468 {
469 $variant_cnt{$s} = 0;
470 }
471 $variant_cnt{$s}++;
472 $a .= "{$variant_cnt{$s}}";
473 }
c454dbcd
RL
474 my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
475 my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
476 if (!grep(/^$togrep$/,
477 split(/;/, defined($variant{$s})?$variant{$s}:""))) {
478 if (defined($variant{$s})) { $variant{$s} .= ";"; }
479 $variant{$s} .= $toadd;
480 }
62dc5aad
RL
481 print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
482 };
483
484 print STDERR "DEBUG: parsing ----------\n" if $debug;
47339f61 485 while(<IN>) {
40e950ae
DSH
486 if (/\/\* Error codes for the \w+ functions\. \*\//)
487 {
488 undef @tag;
489 last;
490 }
47339f61
DSH
491 if ($line ne '') {
492 $_ = $line . $_;
493 $line = '';
d02b48c6 494 }
47339f61
DSH
495
496 if (/\\$/) {
d399fdf8
RL
497 chomp; # remove eol
498 chop; # remove ending backslash
47339f61
DSH
499 $line = $_;
500 next;
501 }
502
68e57536
AP
503 if(/\/\*/) {
504 if (not /\*\//) { # multiline comment...
505 $line = $_; # ... just accumulate
506 next;
507 } else {
508 s/\/\*.*?\*\///gs;# wipe it
509 }
510 }
511
47339f61 512 if ($cpp) {
68e57536
AP
513 $cpp++ if /^#\s*if/;
514 $cpp-- if /^#\s*endif/;
47339f61
DSH
515 next;
516 }
68e57536 517 $cpp = 1 if /^#.*ifdef.*cplusplus/;
47339f61 518
47339f61 519 s/{[^{}]*}//gs; # ignore {} blocks
6cb68620 520 print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
d399fdf8 521 print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
3f07fe09 522 if (/^\#\s*ifndef\s+(.*)/) {
d399fdf8 523 push(@tag,"-");
d02b48c6
RE
524 push(@tag,$1);
525 $tag{$1}=-1;
d399fdf8 526 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
3f07fe09 527 } elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
d399fdf8
RL
528 push(@tag,"-");
529 if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
530 my $tmp_1 = $1;
531 my $tmp_;
532 foreach $tmp_ (split '\&\&',$tmp_1) {
533 $tmp_ =~ /!defined\(([^\)]+)\)/;
534 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
535 push(@tag,$1);
536 $tag{$1}=-1;
537 }
538 } else {
539 print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
540 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
541 push(@tag,$1);
542 $tag{$1}=-1;
543 }
8aa36bca 544 } elsif (/^\#\s*ifdef\s+(\S*)/) {
d399fdf8 545 push(@tag,"-");
d02b48c6
RE
546 push(@tag,$1);
547 $tag{$1}=1;
d399fdf8 548 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
3f07fe09 549 } elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
d399fdf8
RL
550 push(@tag,"-");
551 if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
552 my $tmp_1 = $1;
553 my $tmp_;
554 foreach $tmp_ (split '\|\|',$tmp_1) {
555 $tmp_ =~ /defined\(([^\)]+)\)/;
556 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
557 push(@tag,$1);
558 $tag{$1}=1;
559 }
560 } else {
561 print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
562 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
563 push(@tag,$1);
564 $tag{$1}=1;
565 }
948d0125 566 } elsif (/^\#\s*error\s+(\w+) is disabled\./) {
d399fdf8
RL
567 my $tag_i = $#tag;
568 while($tag[$tag_i] ne "-") {
569 if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
570 $tag{$tag[$tag_i]}=2;
571 print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
572 }
573 $tag_i--;
948d0125 574 }
47339f61 575 } elsif (/^\#\s*endif/) {
d399fdf8 576 my $tag_i = $#tag;
665560e9 577 while($tag_i > 0 && $tag[$tag_i] ne "-") {
d399fdf8
RL
578 my $t=$tag[$tag_i];
579 print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
580 if ($tag{$t}==2) {
581 $tag{$t}=-1;
582 } else {
583 $tag{$t}=0;
584 }
585 print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
586 pop(@tag);
587 if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
588 $t=$1;
589 } else {
590 $t="";
591 }
592 if ($t ne ""
593 && !grep(/^$t$/, @known_algorithms)) {
594 $unknown_algorithms{$t} = 1;
595 #print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
596 }
597 $tag_i--;
948d0125 598 }
d02b48c6 599 pop(@tag);
47339f61 600 } elsif (/^\#\s*else/) {
d399fdf8
RL
601 my $tag_i = $#tag;
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;
948d0125 620 } elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
2ae87d46 621 && $symhacking && $tag{'TRUE'} != -1) {
62dc5aad
RL
622 # This is for aliasing. When we find an alias,
623 # we have to invert
624 &$make_variant($1,$2);
625 print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
948d0125
RL
626 }
627 if (/^\#/) {
267a1927
RL
628 @current_platforms =
629 grep(!/^$/,
d399fdf8
RL
630 map { $tag{$_} == 1 ? $_ :
631 $tag{$_} == -1 ? "!".$_ : "" }
267a1927 632 @known_platforms);
d399fdf8
RL
633 push @current_platforms
634 , grep(!/^$/,
635 map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
636 $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_ : "" }
637 @known_ossl_platforms);
267a1927
RL
638 @current_algorithms =
639 grep(!/^$/,
cf1b7d96 640 map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
267a1927
RL
641 @known_algorithms);
642 $def .=
643 "#INFO:"
644 .join(',',@current_platforms).":"
645 .join(',',@current_algorithms).";";
47339f61
DSH
646 next;
647 }
2ae87d46
RL
648 if ($tag{'TRUE'} != -1) {
649 if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
650 next;
651 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
652 $def .= "int d2i_$3(void);";
653 $def .= "int i2d_$3(void);";
62dc5aad
RL
654 # Variant for platforms that do not
655 # have to access globale variables
656 # in shared libraries through functions
657 $def .=
658 "#INFO:"
659 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
660 .join(',',@current_algorithms).";";
2ae87d46 661 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
662 $def .=
663 "#INFO:"
664 .join(',',@current_platforms).":"
665 .join(',',@current_algorithms).";";
666 # Variant for platforms that have to
667 # access globale variables in shared
668 # libraries through functions
669 &$make_variant("$2_it","$2_it",
670 "EXPORT_VAR_AS_FUNCTION",
671 "FUNCTION");
2ae87d46
RL
672 next;
673 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
674 $def .= "int d2i_$3(void);";
675 $def .= "int i2d_$3(void);";
676 $def .= "int $3_free(void);";
677 $def .= "int $3_new(void);";
62dc5aad
RL
678 # Variant for platforms that do not
679 # have to access globale variables
680 # in shared libraries through functions
681 $def .=
682 "#INFO:"
683 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
684 .join(',',@current_algorithms).";";
2ae87d46 685 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
686 $def .=
687 "#INFO:"
688 .join(',',@current_platforms).":"
689 .join(',',@current_algorithms).";";
690 # Variant for platforms that have to
691 # access globale variables in shared
692 # libraries through functions
693 &$make_variant("$2_it","$2_it",
694 "EXPORT_VAR_AS_FUNCTION",
695 "FUNCTION");
696 next;
2ae87d46
RL
697 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
698 /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
699 $def .= "int d2i_$1(void);";
700 $def .= "int i2d_$1(void);";
701 $def .= "int $1_free(void);";
702 $def .= "int $1_new(void);";
62dc5aad
RL
703 # Variant for platforms that do not
704 # have to access globale variables
705 # in shared libraries through functions
706 $def .=
707 "#INFO:"
708 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
709 .join(',',@current_algorithms).";";
2ae87d46 710 $def .= "OPENSSL_EXTERN int $1_it;";
62dc5aad
RL
711 $def .=
712 "#INFO:"
713 .join(',',@current_platforms).":"
714 .join(',',@current_algorithms).";";
715 # Variant for platforms that have to
716 # access globale variables in shared
717 # libraries through functions
718 &$make_variant("$1_it","$1_it",
719 "EXPORT_VAR_AS_FUNCTION",
720 "FUNCTION");
2ae87d46
RL
721 next;
722 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
723 $def .= "int d2i_$2(void);";
724 $def .= "int i2d_$2(void);";
62dc5aad
RL
725 # Variant for platforms that do not
726 # have to access globale variables
727 # in shared libraries through functions
728 $def .=
729 "#INFO:"
730 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
731 .join(',',@current_algorithms).";";
2ae87d46 732 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
733 $def .=
734 "#INFO:"
735 .join(',',@current_platforms).":"
736 .join(',',@current_algorithms).";";
737 # Variant for platforms that have to
738 # access globale variables in shared
739 # libraries through functions
740 &$make_variant("$2_it","$2_it",
741 "EXPORT_VAR_AS_FUNCTION",
742 "FUNCTION");
2ae87d46 743 next;
ea3675b5
DSH
744 } elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
745 $def .= "int $1_free(void);";
746 $def .= "int $1_new(void);";
747 next;
2ae87d46
RL
748 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
749 $def .= "int d2i_$2(void);";
750 $def .= "int i2d_$2(void);";
751 $def .= "int $2_free(void);";
752 $def .= "int $2_new(void);";
62dc5aad
RL
753 # Variant for platforms that do not
754 # have to access globale variables
755 # in shared libraries through functions
756 $def .=
757 "#INFO:"
758 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
759 .join(',',@current_algorithms).";";
2ae87d46 760 $def .= "OPENSSL_EXTERN int $2_it;";
62dc5aad
RL
761 $def .=
762 "#INFO:"
763 .join(',',@current_platforms).":"
764 .join(',',@current_algorithms).";";
765 # Variant for platforms that have to
766 # access globale variables in shared
767 # libraries through functions
768 &$make_variant("$2_it","$2_it",
769 "EXPORT_VAR_AS_FUNCTION",
770 "FUNCTION");
2ae87d46 771 next;
62dc5aad
RL
772 } elsif (/^\s*DECLARE_ASN1_ITEM\s*\(\s*(\w*)\s*\)/) {
773 # Variant for platforms that do not
774 # have to access globale variables
775 # in shared libraries through functions
776 $def .=
777 "#INFO:"
778 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
779 .join(',',@current_algorithms).";";
2ae87d46 780 $def .= "OPENSSL_EXTERN int $1_it;";
62dc5aad
RL
781 $def .=
782 "#INFO:"
783 .join(',',@current_platforms).":"
784 .join(',',@current_algorithms).";";
785 # Variant for platforms that have to
786 # access globale variables in shared
787 # libraries through functions
788 &$make_variant("$1_it","$1_it",
789 "EXPORT_VAR_AS_FUNCTION",
790 "FUNCTION");
2ae87d46 791 next;
f86abc2e 792 } elsif (/^\s*DECLARE_ASN1_NDEF_FUNCTION\s*\(\s*(\w*)\s*\)/) {
97ebe047 793 $def .= "int i2d_$1_NDEF(void);";
2ae87d46
RL
794 } elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
795 next;
16094305
DSH
796 } elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION\s*\(\s*(\w*)\s*\)/) {
797 $def .= "int $1_print_ctx(void);";
798 next;
799 } elsif (/^\s*DECLARE_ASN1_PRINT_FUNCTION_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
800 $def .= "int $2_print_ctx(void);";
801 next;
62dc5aad
RL
802 } elsif (/^\s*DECLARE_PKCS12_STACK_OF\s*\(\s*(\w*)\s*\)/) {
803 next;
2ae87d46 804 } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
47738cba
AP
805 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ||
806 /^DECLARE_PEM_rw_const\s*\(\s*(\w*)\s*,/ ) {
2ae87d46
RL
807 # Things not in Win16
808 $def .=
809 "#INFO:"
810 .join(',',"!WIN16",@current_platforms).":"
811 .join(',',@current_algorithms).";";
812 $def .= "int PEM_read_$1(void);";
813 $def .= "int PEM_write_$1(void);";
814 $def .=
815 "#INFO:"
816 .join(',',@current_platforms).":"
817 .join(',',@current_algorithms).";";
818 # Things that are everywhere
819 $def .= "int PEM_read_bio_$1(void);";
820 $def .= "int PEM_write_bio_$1(void);";
821 next;
822 } elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
823 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
824 # Things not in Win16
825 $def .=
826 "#INFO:"
827 .join(',',"!WIN16",@current_platforms).":"
828 .join(',',@current_algorithms).";";
829 $def .= "int PEM_write_$1(void);";
830 $def .=
831 "#INFO:"
832 .join(',',@current_platforms).":"
833 .join(',',@current_algorithms).";";
834 # Things that are everywhere
835 $def .= "int PEM_write_bio_$1(void);";
836 next;
837 } elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
838 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
839 # Things not in Win16
840 $def .=
841 "#INFO:"
842 .join(',',"!WIN16",@current_platforms).":"
843 .join(',',@current_algorithms).";";
844 $def .= "int PEM_read_$1(void);";
845 $def .=
846 "#INFO:"
847 .join(',',@current_platforms).":"
848 .join(',',@current_algorithms).";";
849 # Things that are everywhere
850 $def .= "int PEM_read_bio_$1(void);";
851 next;
62dc5aad
RL
852 } elsif (/^OPENSSL_DECLARE_GLOBAL\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
853 # Variant for platforms that do not
854 # have to access globale variables
855 # in shared libraries through functions
856 $def .=
857 "#INFO:"
858 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
859 .join(',',@current_algorithms).";";
860 $def .= "OPENSSL_EXTERN int _shadow_$2;";
861 $def .=
862 "#INFO:"
863 .join(',',@current_platforms).":"
864 .join(',',@current_algorithms).";";
865 # Variant for platforms that have to
866 # access globale variables in shared
867 # libraries through functions
868 &$make_variant("_shadow_$2","_shadow_$2",
869 "EXPORT_VAR_AS_FUNCTION",
870 "FUNCTION");
2ae87d46 871 } elsif ($tag{'CONST_STRICT'} != 1) {
948d0125 872 if (/\{|\/\*|\([^\)]*$/) {
47339f61
DSH
873 $line = $_;
874 } else {
875 $def .= $_;
876 }
d02b48c6
RE
877 }
878 }
2ae87d46 879 }
d02b48c6 880 close(IN);
47339f61 881
948d0125
RL
882 my $algs;
883 my $plays;
884
62dc5aad 885 print STDERR "DEBUG: postprocessing ----------\n" if $debug;
47339f61 886 foreach (split /;/, $def) {
948d0125 887 my $s; my $k = "FUNCTION"; my $p; my $a;
47339f61
DSH
888 s/^[\n\s]*//g;
889 s/[\n\s]*$//g;
948d0125 890 next if(/\#undef/);
47339f61 891 next if(/typedef\W/);
948d0125
RL
892 next if(/\#define/);
893
68e57536
AP
894 # Reduce argument lists to empty ()
895 # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
896 while(/\(.*\)/s) {
897 s/\([^\(\)]+\)/\{\}/gs;
898 s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
899 }
900 # pretend as we didn't use curly braces: {} -> ()
901 s/\{\}/\(\)/gs;
902
903 s/STACK_OF\(\)/void/gs;
174c86a2 904 s/LHASH_OF\(\)/void/gs;
68e57536 905
62dc5aad 906 print STDERR "DEBUG: \$_ = \"$_\"\n" if $debug;
948d0125
RL
907 if (/^\#INFO:([^:]*):(.*)$/) {
908 $plats = $1;
909 $algs = $2;
89eeccac 910 print STDERR "DEBUG: found info on platforms ($plats) and algorithms ($algs)\n" if $debug;
948d0125 911 next;
62dc5aad 912 } elsif (/^\s*OPENSSL_EXTERN\s.*?(\w+(\{[0-9]+\})?)(\[[0-9]*\])*\s*$/) {
948d0125
RL
913 $s = $1;
914 $k = "VARIABLE";
89eeccac 915 print STDERR "DEBUG: found external variable $s\n" if $debug;
68e57536 916 } elsif (/TYPEDEF_\w+_OF/s) {
47339f61 917 next;
68e57536
AP
918 } elsif (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
919 $s = $1; # a function name!
89eeccac 920 print STDERR "DEBUG: found function $s\n" if $debug;
47339f61
DSH
921 } elsif (/\(/ and not (/=/)) {
922 print STDERR "File $file: cannot parse: $_;\n";
948d0125
RL
923 next;
924 } else {
925 next;
926 }
927
928 $syms{$s} = 1;
929 $kind{$s} = $k;
930
931 $p = $plats;
932 $a = $algs;
933 $a .= ",BF" if($s =~ /EVP_bf/);
934 $a .= ",CAST" if($s =~ /EVP_cast/);
935 $a .= ",DES" if($s =~ /EVP_des/);
936 $a .= ",DSA" if($s =~ /EVP_dss/);
937 $a .= ",IDEA" if($s =~ /EVP_idea/);
938 $a .= ",MD2" if($s =~ /EVP_md2/);
939 $a .= ",MD4" if($s =~ /EVP_md4/);
940 $a .= ",MD5" if($s =~ /EVP_md5/);
941 $a .= ",RC2" if($s =~ /EVP_rc2/);
942 $a .= ",RC4" if($s =~ /EVP_rc4/);
943 $a .= ",RC5" if($s =~ /EVP_rc5/);
944 $a .= ",RIPEMD" if($s =~ /EVP_ripemd/);
945 $a .= ",SHA" if($s =~ /EVP_sha/);
946 $a .= ",RSA" if($s =~ /EVP_(Open|Seal)(Final|Init)/);
947 $a .= ",RSA" if($s =~ /PEM_Seal(Final|Init|Update)/);
948 $a .= ",RSA" if($s =~ /RSAPrivateKey/);
949 $a .= ",RSA" if($s =~ /SSLv23?_((client|server)_)?method/);
950
62dc5aad
RL
951 $platform{$s} =
952 &reduce_platforms((defined($platform{$s})?$platform{$s}.',':"").$p);
948d0125
RL
953 $algorithm{$s} .= ','.$a;
954
62dc5aad 955 if (defined($variant{$s})) {
c454dbcd
RL
956 foreach $v (split /;/,$variant{$s}) {
957 (my $r, my $p, my $k) = split(/:/,$v);
958 my $ip = join ',',map({ /^!(.*)$/ ? $1 : "!".$_ } split /,/, $p);
959 $syms{$r} = 1;
960 if (!defined($k)) { $k = $kind{$s}; }
961 $kind{$r} = $k."(".$s.")";
962 $algorithm{$r} = $algorithm{$s};
963 $platform{$r} = &reduce_platforms($platform{$s}.",".$p.",".$p);
964 $platform{$s} = &reduce_platforms($platform{$s}.','.$ip.','.$ip);
965 print STDERR "DEBUG: \$variant{\"$s\"} = ",$v,"; \$r = $r; \$p = ",$platform{$r},"; \$a = ",$algorithm{$r},"; \$kind = ",$kind{$r},"\n" if $debug;
966 }
47339f61 967 }
62dc5aad 968 print STDERR "DEBUG: \$s = $s; \$p = ",$platform{$s},"; \$a = ",$algorithm{$s},"; \$kind = ",$kind{$s},"\n" if $debug;
d02b48c6 969 }
d02b48c6
RE
970 }
971
948d0125 972 # Prune the returned symbols
47339f61 973
948d0125 974 delete $syms{"bn_dump1"};
948d0125
RL
975 $platform{"BIO_s_log"} .= ",!WIN32,!WIN16,!macintosh";
976
2ae87d46
RL
977 $platform{"PEM_read_NS_CERT_SEQ"} = "VMS";
978 $platform{"PEM_write_NS_CERT_SEQ"} = "VMS";
979 $platform{"PEM_read_P8_PRIV_KEY_INFO"} = "VMS";
980 $platform{"PEM_write_P8_PRIV_KEY_INFO"} = "VMS";
af55c09d
RL
981 $platform{"EVP_sha384"} = "!VMSVAX";
982 $platform{"EVP_sha512"} = "!VMSVAX";
983 $platform{"SHA384_Init"} = "!VMSVAX";
984 $platform{"SHA384_Transform"} = "!VMSVAX";
985 $platform{"SHA384_Update"} = "!VMSVAX";
986 $platform{"SHA384_Final"} = "!VMSVAX";
987 $platform{"SHA384"} = "!VMSVAX";
988 $platform{"SHA512_Init"} = "!VMSVAX";
989 $platform{"SHA512_Transform"} = "!VMSVAX";
990 $platform{"SHA512_Update"} = "!VMSVAX";
991 $platform{"SHA512_Final"} = "!VMSVAX";
992 $platform{"SHA512"} = "!VMSVAX";
993
2ae87d46 994
948d0125
RL
995 # Info we know about
996
948d0125
RL
997 push @ret, map { $_."\\".&info_string($_,"EXIST",
998 $platform{$_},
999 $kind{$_},
1000 $algorithm{$_}) } keys %syms;
1001
3f07fe09
RL
1002 if (keys %unknown_algorithms) {
1003 print STDERR "WARNING: mkdef.pl doesn't know the following algorithms:\n";
1004 print STDERR "\t",join("\n\t",keys %unknown_algorithms),"\n";
1005 }
948d0125
RL
1006 return(@ret);
1007}
1008
62dc5aad
RL
1009# Param: string of comma-separated platform-specs.
1010sub reduce_platforms
1011{
1012 my ($platforms) = @_;
948d0125
RL
1013 my $pl = defined($platforms) ? $platforms : "";
1014 my %p = map { $_ => 0 } split /,/, $pl;
948d0125
RL
1015 my $ret;
1016
62dc5aad
RL
1017 print STDERR "DEBUG: Entered reduce_platforms with \"$platforms\"\n"
1018 if $debug;
948d0125
RL
1019 # We do this, because if there's code like the following, it really
1020 # means the function exists in all cases and should therefore be
1021 # everywhere. By increasing and decreasing, we may attain 0:
1022 #
1023 # ifndef WIN16
1024 # int foo();
1025 # else
1026 # int _fat foo();
1027 # endif
1028 foreach $platform (split /,/, $pl) {
1029 if ($platform =~ /^!(.*)$/) {
1030 $p{$1}--;
1031 } else {
1032 $p{$platform}++;
d02b48c6 1033 }
47339f61 1034 }
948d0125
RL
1035 foreach $platform (keys %p) {
1036 if ($p{$platform} == 0) { delete $p{$platform}; }
d02b48c6
RE
1037 }
1038
948d0125 1039 delete $p{""};
62dc5aad 1040
c454dbcd 1041 $ret = join(',',sort(map { $p{$_} < 0 ? "!".$_ : $_ } keys %p));
62dc5aad
RL
1042 print STDERR "DEBUG: Exiting reduce_platforms with \"$ret\"\n"
1043 if $debug;
1044 return $ret;
1045}
1046
1047sub info_string {
1048 (my $symbol, my $exist, my $platforms, my $kind, my $algorithms) = @_;
1049
1050 my %a = defined($algorithms) ?
1051 map { $_ => 1 } split /,/, $algorithms : ();
1052 my $k = defined($kind) ? $kind : "FUNCTION";
1053 my $ret;
1054 my $p = &reduce_platforms($platforms);
1055
948d0125 1056 delete $a{""};
d02b48c6 1057
948d0125 1058 $ret = $exist;
62dc5aad 1059 $ret .= ":".$p;
948d0125 1060 $ret .= ":".$k;
62dc5aad 1061 $ret .= ":".join(',',sort keys %a);
948d0125
RL
1062 return $ret;
1063}
1064
1065sub maybe_add_info {
1066 (my $name, *nums, my @symbols) = @_;
1067 my $sym;
1068 my $new_info = 0;
451e60e9 1069 my %syms=();
948d0125
RL
1070
1071 print STDERR "Updating $name info\n";
1072 foreach $sym (@symbols) {
1073 (my $s, my $i) = split /\\/, $sym;
948d0125 1074 if (defined($nums{$s})) {
62dc5aad 1075 $i =~ s/^(.*?:.*?:\w+)(\(\w+\))?/$1/;
948d0125
RL
1076 (my $n, my $dummy) = split /\\/, $nums{$s};
1077 if (!defined($dummy) || $i ne $dummy) {
1078 $nums{$s} = $n."\\".$i;
1079 $new_info++;
d399fdf8 1080 print STDERR "DEBUG: maybe_add_info for $s: \"$dummy\" => \"$i\"\n" if $debug;
948d0125
RL
1081 }
1082 }
62dc5aad 1083 $syms{$s} = 1;
451e60e9
RL
1084 }
1085
1086 my @s=sort { &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n") } keys %nums;
1087 foreach $sym (@s) {
1088 (my $n, my $i) = split /\\/, $nums{$sym};
62dc5aad 1089 if (!defined($syms{$sym}) && $i !~ /^NOEXIST:/) {
451e60e9 1090 $new_info++;
62dc5aad 1091 print STDERR "DEBUG: maybe_add_info for $sym: -> undefined\n" if $debug;
451e60e9 1092 }
948d0125
RL
1093 }
1094 if ($new_info) {
1095 print STDERR "$new_info old symbols got an info update\n";
6d50071e
RL
1096 if (!$do_rewrite) {
1097 print STDERR "You should do a rewrite to fix this.\n";
1098 }
948d0125
RL
1099 } else {
1100 print STDERR "No old symbols needed info update\n";
1101 }
47339f61 1102}
d02b48c6 1103
62dc5aad
RL
1104# Param: string of comma-separated keywords, each possibly prefixed with a "!"
1105sub is_valid
1106{
1107 my ($keywords_txt,$platforms) = @_;
1108 my (@keywords) = split /,/,$keywords_txt;
d3fdc27a 1109 my ($falsesum, $truesum) = (0, 1);
62dc5aad
RL
1110
1111 # Param: one keyword
1112 sub recognise
1113 {
1114 my ($keyword,$platforms) = @_;
1115
1116 if ($platforms) {
1117 # platforms
af55c09d
RL
1118 if ($keyword eq "VMSVAX" && $VMSVAX) { return 1; }
1119 if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; }
62dc5aad
RL
1120 if ($keyword eq "VMS" && $VMS) { return 1; }
1121 if ($keyword eq "WIN32" && $W32) { return 1; }
1122 if ($keyword eq "WIN16" && $W16) { return 1; }
1123 if ($keyword eq "WINNT" && $NT) { return 1; }
cd4c36ad 1124 if ($keyword eq "OS2" && $OS2) { return 1; }
62dc5aad
RL
1125 # Special platforms:
1126 # EXPORT_VAR_AS_FUNCTION means that global variables
1127 # will be represented as functions. This currently
1128 # only happens on VMS-VAX.
2d10c715 1129 if ($keyword eq "EXPORT_VAR_AS_FUNCTION" && ($VMSVAX || $W32 || $W16)) {
62dc5aad
RL
1130 return 1;
1131 }
53f76337
DSH
1132 if ($keyword eq "OPENSSL_FIPS" && $fips) {
1133 return 1;
1134 }
8931b30d 1135 if ($keyword eq "ZLIB" && $zlib) { return 1; }
62dc5aad
RL
1136 return 0;
1137 } else {
1138 # algorithms
1139 if ($keyword eq "RC2" && $no_rc2) { return 0; }
1140 if ($keyword eq "RC4" && $no_rc4) { return 0; }
1141 if ($keyword eq "RC5" && $no_rc5) { return 0; }
1142 if ($keyword eq "IDEA" && $no_idea) { return 0; }
1143 if ($keyword eq "DES" && $no_des) { return 0; }
1144 if ($keyword eq "BF" && $no_bf) { return 0; }
1145 if ($keyword eq "CAST" && $no_cast) { return 0; }
1146 if ($keyword eq "MD2" && $no_md2) { return 0; }
1147 if ($keyword eq "MD4" && $no_md4) { return 0; }
1148 if ($keyword eq "MD5" && $no_md5) { return 0; }
1149 if ($keyword eq "SHA" && $no_sha) { return 0; }
1150 if ($keyword eq "RIPEMD" && $no_ripemd) { return 0; }
1151 if ($keyword eq "MDC2" && $no_mdc2) { return 0; }
ec645d90 1152 if ($keyword eq "WHIRLPOOL" && $no_whirlpool) { return 0; }
62dc5aad
RL
1153 if ($keyword eq "RSA" && $no_rsa) { return 0; }
1154 if ($keyword eq "DSA" && $no_dsa) { return 0; }
1155 if ($keyword eq "DH" && $no_dh) { return 0; }
26a81abf 1156 if ($keyword eq "EC" && $no_ec) { return 0; }
4d94ae00 1157 if ($keyword eq "ECDSA" && $no_ecdsa) { return 0; }
e172d60d 1158 if ($keyword eq "ECDH" && $no_ecdh) { return 0; }
62dc5aad
RL
1159 if ($keyword eq "HMAC" && $no_hmac) { return 0; }
1160 if ($keyword eq "AES" && $no_aes) { return 0; }
f3dea9a5 1161 if ($keyword eq "CAMELLIA" && $no_camellia) { return 0; }
96afc1cf 1162 if ($keyword eq "SEED" && $no_seed) { return 0; }
26a81abf
RL
1163 if ($keyword eq "EVP" && $no_evp) { return 0; }
1164 if ($keyword eq "LHASH" && $no_lhash) { return 0; }
1165 if ($keyword eq "STACK" && $no_stack) { return 0; }
1166 if ($keyword eq "ERR" && $no_err) { return 0; }
1167 if ($keyword eq "BUFFER" && $no_buffer) { return 0; }
1168 if ($keyword eq "BIO" && $no_bio) { return 0; }
1169 if ($keyword eq "COMP" && $no_comp) { return 0; }
1170 if ($keyword eq "DSO" && $no_dso) { return 0; }
62dc5aad 1171 if ($keyword eq "KRB5" && $no_krb5) { return 0; }
0b13e9f0 1172 if ($keyword eq "ENGINE" && $no_engine) { return 0; }
5cd48abf 1173 if ($keyword eq "HW" && $no_hw) { return 0; }
62dc5aad 1174 if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
6cb68620 1175 if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
987bebaf 1176 if ($keyword eq "GMP" && $no_gmp) { return 0; }
d137b56a 1177 if ($keyword eq "RFC3779" && $no_rfc3779) { return 0; }
c20276e4
DSH
1178 if ($keyword eq "TLSEXT" && $no_tlsext) { return 0; }
1179 if ($keyword eq "PSK" && $no_psk) { return 0; }
8931b30d 1180 if ($keyword eq "CMS" && $no_cms) { return 0; }
36246be9
DSH
1181 if ($keyword eq "EC2M" && $no_ec2m) { return 0; }
1182 if ($keyword eq "NEXTPROTONEG" && $no_nextprotoneg) { return 0; }
06ddf8eb 1183 if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
d8bd55a3 1184 if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
79bd20fd 1185 if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
edc032b5 1186 if ($keyword eq "SRP" && $no_srp) { return 0; }
4ccfe5f4 1187 if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
62dc5aad
RL
1188
1189 # Nothing recognise as true
1190 return 1;
1191 }
1192 }
1193
1194 foreach $k (@keywords) {
1195 if ($k =~ /^!(.*)$/) {
1196 $falsesum += &recognise($1,$platforms);
1197 } else {
d3fdc27a 1198 $truesum *= &recognise($k,$platforms);
62dc5aad
RL
1199 }
1200 }
1201 print STDERR "DEBUG: [",$#keywords,",",$#keywords < 0,"] is_valid($keywords_txt) => (\!$falsesum) && $truesum = ",(!$falsesum) && $truesum,"\n" if $debug;
1202 return (!$falsesum) && $truesum;
1203}
1204
12aefe78
DSH
1205sub print_test_file
1206{
62dc5aad 1207 (*OUT,my $name,*nums,my $testall,my @symbols)=@_;
0f583f69 1208 my $n = 1; my @e; my @r;
948d0125
RL
1209 my $sym; my $prev = ""; my $prefSSLeay;
1210
62dc5aad
RL
1211 (@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
1212 (@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:.*/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:.*/,@symbols);
948d0125
RL
1213 @symbols=((sort @e),(sort @r));
1214
1215 foreach $sym (@symbols) {
1216 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
62dc5aad
RL
1217 my $v = 0;
1218 $v = 1 if $i=~ /^.*?:.*?:VARIABLE/;
1219 my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1220 my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1221 if (!defined($nums{$s})) {
1222 print STDERR "Warning: $s does not have a number assigned\n"
1223 if(!$do_update);
1224 } elsif (is_valid($p,1) && is_valid($a,0)) {
1225 my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1226 if ($prev eq $s2) {
1227 print OUT "\t/* The following has already appeared previously */\n";
1228 print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1229 }
1230 $prev = $s2; # To warn about duplicates...
1231
1232 ($nn,$ni)=($nums{$s2} =~ /^(.*?)\\(.*)$/);
1233 if ($v) {
1234 print OUT "\textern int $s2; /* type unknown */ /* $nn $ni */\n";
967f4ca8 1235 } else {
62dc5aad 1236 print OUT "\textern int $s2(); /* type unknown */ /* $nn $ni */\n";
967f4ca8 1237 }
12aefe78
DSH
1238 }
1239 }
1240}
1241
0b352c58
RL
1242sub get_version {
1243 local *MF;
1244 my $v = '?';
52272327 1245 open MF, 'Makefile' or return $v;
0b352c58
RL
1246 while (<MF>) {
1247 $v = $1, last if /^VERSION=(.*?)\s*$/;
1248 }
1249 close MF;
1250 return $v;
1251}
1252
d02b48c6 1253sub print_def_file
47339f61 1254{
948d0125 1255 (*OUT,my $name,*nums,my @symbols)=@_;
62dc5aad 1256 my $n = 1; my @e; my @r; my @v; my $prev="";
cd4c36ad 1257 my $liboptions="";
0b352c58
RL
1258 my $libname = $name;
1259 my $http_vendor = 'www.openssl.org/';
1260 my $version = get_version();
1261 my $what = "OpenSSL: implementation of Secure Socket Layer";
1262 my $description = "$what $version, $name - http://$http_vendor";
d02b48c6 1263
06c68491 1264 if ($W32)
0b352c58 1265 { $libname.="32"; }
cd4c36ad 1266 elsif ($W16)
0b352c58 1267 { $libname.="16"; }
cd4c36ad 1268 elsif ($OS2)
0b352c58
RL
1269 { # DLL names should not clash on the whole system.
1270 # However, they should not have any particular relationship
1271 # to the name of the static library. Chose descriptive names
1272 # (must be at most 8 chars).
1273 my %translate = (ssl => 'open_ssl', crypto => 'cryptssl');
1274 $libname = $translate{$name} || $name;
1275 $liboptions = <<EOO;
1276INITINSTANCE
1277DATA MULTIPLE NONSHARED
1278EOO
1279 # Vendor field can't contain colon, drat; so we omit http://
1280 $description = "\@#$http_vendor:$version#\@$what; DLL for library $name. Build for EMX -Zmtd";
1281 }
d02b48c6
RE
1282
1283 print OUT <<"EOF";
1284;
9b3086fe 1285; Definition file for the DLL version of the $name library from OpenSSL
d02b48c6
RE
1286;
1287
0b352c58 1288LIBRARY $libname $liboptions
d02b48c6 1289
d02b48c6
RE
1290EOF
1291
cd4c36ad 1292 if ($W16) {
d02b48c6
RE
1293 print <<"EOF";
1294CODE PRELOAD MOVEABLE
1295DATA PRELOAD MOVEABLE SINGLE
1296
1297EXETYPE WINDOWS
1298
1299HEAPSIZE 4096
1300STACKSIZE 8192
1301
1302EOF
47339f61 1303 }
d02b48c6
RE
1304
1305 print "EXPORTS\n";
1306
62dc5aad
RL
1307 (@e)=grep(/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
1308 (@r)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:FUNCTION/ && !/^SSLeay(\{[0-9]+\})?\\.*?:.*?:FUNCTION/,@symbols);
1309 (@v)=grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:VARIABLE/,@symbols);
9c67ab2f 1310 @symbols=((sort @e),(sort @r), (sort @v));
d02b48c6 1311
d02b48c6 1312
948d0125
RL
1313 foreach $sym (@symbols) {
1314 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
9c67ab2f 1315 my $v = 0;
62dc5aad 1316 $v = 1 if $i =~ /^.*?:.*?:VARIABLE/;
948d0125
RL
1317 if (!defined($nums{$s})) {
1318 printf STDERR "Warning: $s does not have a number assigned\n"
62dc5aad 1319 if(!$do_update);
47339f61 1320 } else {
62dc5aad 1321 (my $n, my $dummy) = split /\\/, $nums{$s};
d63b8db8 1322 my %pf = ();
62dc5aad
RL
1323 my $p = ($i =~ /^[^:]*:([^:]*):/,$1);
1324 my $a = ($i =~ /^[^:]*:[^:]*:[^:]*:([^:]*)/,$1);
1325 if (is_valid($p,1) && is_valid($a,0)) {
1326 my $s2 = ($s =~ /^(.*?)(\{[0-9]+\})?$/, $1);
1327 if ($prev eq $s2) {
1328 print STDERR "Warning: Symbol '",$s2,"' redefined. old=",($nums{$prev} =~ /^(.*?)\\/,$1),", new=",($nums{$s2} =~ /^(.*?)\\/,$1),"\n";
1329 }
1330 $prev = $s2; # To warn about duplicates...
cd4c36ad 1331 if($v && !$OS2) {
b4f682d3 1332 printf OUT " %s%-39s @%-8d DATA\n",($W32)?"":"_",$s2,$n;
9c67ab2f 1333 } else {
cd4c36ad 1334 printf OUT " %s%-39s @%d\n",($W32||$OS2)?"":"_",$s2,$n;
9c67ab2f 1335 }
965c1775 1336 }
d02b48c6 1337 }
d02b48c6 1338 }
47339f61
DSH
1339 printf OUT "\n";
1340}
d02b48c6
RE
1341
1342sub load_numbers
47339f61
DSH
1343{
1344 my($name)=@_;
1345 my(@a,%ret);
d02b48c6 1346
55a9cc6e 1347 $max_num = 0;
948d0125
RL
1348 $num_noinfo = 0;
1349 $prev = "";
62dc5aad 1350 $prev_cnt = 0;
55a9cc6e 1351
d02b48c6 1352 open(IN,"<$name") || die "unable to open $name:$!\n";
47339f61 1353 while (<IN>) {
d02b48c6
RE
1354 chop;
1355 s/#.*$//;
1356 next if /^\s*$/;
1357 @a=split;
948d0125 1358 if (defined $ret{$a[0]}) {
62dc5aad
RL
1359 # This is actually perfectly OK
1360 #print STDERR "Warning: Symbol '",$a[0],"' redefined. old=",$ret{$a[0]},", new=",$a[1],"\n";
948d0125
RL
1361 }
1362 if ($max_num > $a[1]) {
1363 print STDERR "Warning: Number decreased from ",$max_num," to ",$a[1],"\n";
1364 }
62dc5aad 1365 elsif ($max_num == $a[1]) {
948d0125
RL
1366 # This is actually perfectly OK
1367 #print STDERR "Warning: Symbol ",$a[0]," has same number as previous ",$prev,": ",$a[1],"\n";
62dc5aad
RL
1368 if ($a[0] eq $prev) {
1369 $prev_cnt++;
1370 $a[0] .= "{$prev_cnt}";
1371 }
1372 }
1373 else {
1374 $prev_cnt = 0;
948d0125
RL
1375 }
1376 if ($#a < 2) {
1377 # Existence will be proven later, in do_defs
1378 $ret{$a[0]}=$a[1];
1379 $num_noinfo++;
1380 } else {
1381 $ret{$a[0]}=$a[1]."\\".$a[2]; # \\ is a special marker
1382 }
55a9cc6e 1383 $max_num = $a[1] if $a[1] > $max_num;
948d0125
RL
1384 $prev=$a[0];
1385 }
1386 if ($num_noinfo) {
1387 print STDERR "Warning: $num_noinfo symbols were without info.";
1388 if ($do_rewrite) {
1389 printf STDERR " The rewrite will fix this.\n";
1390 } else {
1391 printf STDERR " You should do a rewrite to fix this.\n";
1392 }
47339f61 1393 }
d02b48c6
RE
1394 close(IN);
1395 return(%ret);
47339f61 1396}
55a9cc6e 1397
948d0125
RL
1398sub parse_number
1399{
1400 (my $str, my $what) = @_;
1401 (my $n, my $i) = split(/\\/,$str);
1402 if ($what eq "n") {
1403 return $n;
1404 } else {
1405 return $i;
1406 }
1407}
1408
1409sub rewrite_numbers
1410{
1411 (*OUT,$name,*nums,@symbols)=@_;
1412 my $thing;
1413
1414 print STDERR "Rewriting $name\n";
1415
62dc5aad 1416 my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
948d0125
RL
1417 my $r; my %r; my %rsyms;
1418 foreach $r (@r) {
1419 (my $s, my $i) = split /\\/, $r;
1420 my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1421 $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1422 $r{$a} = $s."\\".$i;
1423 $rsyms{$s} = 1;
1424 }
1425
451e60e9
RL
1426 my %syms = ();
1427 foreach $_ (@symbols) {
1428 (my $n, my $i) = split /\\/;
1429 $syms{$n} = 1;
1430 }
1431
89eeccac
RL
1432 my @s=sort {
1433 &parse_number($nums{$a},"n") <=> &parse_number($nums{$b},"n")
1434 || $a cmp $b
1435 } keys %nums;
948d0125
RL
1436 foreach $sym (@s) {
1437 (my $n, my $i) = split /\\/, $nums{$sym};
1438 next if defined($i) && $i =~ /^.*?:.*?:\w+\(\w+\)/;
1439 next if defined($rsyms{$sym});
62dc5aad 1440 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
1441 $i="NOEXIST::FUNCTION:"
1442 if !defined($i) || $i eq "" || !defined($syms{$sym});
62dc5aad
RL
1443 my $s2 = $sym;
1444 $s2 =~ s/\{[0-9]+\}$//;
b4f682d3 1445 printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
948d0125
RL
1446 if (exists $r{$sym}) {
1447 (my $s, $i) = split /\\/,$r{$sym};
62dc5aad
RL
1448 my $s2 = $s;
1449 $s2 =~ s/\{[0-9]+\}$//;
b4f682d3 1450 printf OUT "%s%-39s %d\t%s\n","",$s2,$n,$i;
948d0125
RL
1451 }
1452 }
1453}
1454
55a9cc6e 1455sub update_numbers
47339f61 1456{
948d0125
RL
1457 (*OUT,$name,*nums,my $start_num, my @symbols)=@_;
1458 my $new_syms = 0;
1459
1460 print STDERR "Updating $name numbers\n";
1461
62dc5aad 1462 my @r = grep(/^\w+(\{[0-9]+\})?\\.*?:.*?:\w+\(\w+\)/,@symbols);
948d0125
RL
1463 my $r; my %r; my %rsyms;
1464 foreach $r (@r) {
1465 (my $s, my $i) = split /\\/, $r;
1466 my $a = $1 if $i =~ /^.*?:.*?:\w+\((\w+)\)/;
1467 $i =~ s/^(.*?:.*?:\w+)\(\w+\)/$1/;
1468 $r{$a} = $s."\\".$i;
1469 $rsyms{$s} = 1;
1470 }
1471
1472 foreach $sym (@symbols) {
1473 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1474 next if $i =~ /^.*?:.*?:\w+\(\w+\)/;
1475 next if defined($rsyms{$sym});
1476 die "ERROR: Symbol $sym had no info attached to it."
1477 if $i eq "";
1478 if (!exists $nums{$s}) {
1479 $new_syms++;
62dc5aad
RL
1480 my $s2 = $s;
1481 $s2 =~ s/\{[0-9]+\}$//;
b4f682d3 1482 printf OUT "%s%-39s %d\t%s\n","",$s2, ++$start_num,$i;
948d0125 1483 if (exists $r{$s}) {
33b1a4c2 1484 ($s, $i) = split /\\/,$r{$s};
62dc5aad 1485 $s =~ s/\{[0-9]+\}$//;
b4f682d3 1486 printf OUT "%s%-39s %d\t%s\n","",$s, $start_num,$i;
948d0125 1487 }
55a9cc6e 1488 }
47339f61 1489 }
948d0125
RL
1490 if($new_syms) {
1491 print STDERR "$new_syms New symbols added\n";
55a9cc6e 1492 } else {
948d0125
RL
1493 print STDERR "No New symbols Added\n";
1494 }
1495}
1496
1497sub check_existing
1498{
1499 (*nums, my @symbols)=@_;
1500 my %existing; my @remaining;
1501 @remaining=();
1502 foreach $sym (@symbols) {
1503 (my $s, my $i) = $sym =~ /^(.*?)\\(.*)$/;
1504 $existing{$s}=1;
1505 }
1506 foreach $sym (keys %nums) {
1507 if (!exists $existing{$sym}) {
1508 push @remaining, $sym;
1509 }
1510 }
1511 if(@remaining) {
1512 print STDERR "The following symbols do not seem to exist:\n";
1513 foreach $sym (@remaining) {
1514 print STDERR "\t",$sym,"\n";
1515 }
55a9cc6e 1516 }
47339f61 1517}
948d0125 1518