]> git.ipfire.org Git - thirdparty/openssl.git/blame - util/mkdef.pl
It's not just VMS that needs some symbols to be hacked. Let's
[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
RE
7#
8
0f583f69
UM
9my $crypto_num="util/libeay.num";
10my $ssl_num= "util/ssleay.num";
d02b48c6 11
47339f61
DSH
12my $do_update = 0;
13my $do_crypto = 0;
14my $do_ssl = 0;
0f583f69 15my $do_ctest = 0;
967f4ca8 16my $do_ctestall = 0;
0f583f69 17my $rsaref = 0;
47339f61 18
0f583f69
UM
19my $W32=1;
20my $NT=0;
28a98809 21# Set this to make typesafe STACK definitions appear in DEF
e41c8d6a 22my $safe_stack_def = 0;
31ff97b2 23
0f583f69 24my $options="";
31ff97b2
UM
25open(IN,"<Makefile.ssl") || die "unable to open Makefile.ssl!\n";
26while(<IN>) {
27 $options=$1 if (/^OPTIONS=(.*)$/);
28}
ce457a54 29close(IN);
31ff97b2 30
0f583f69
UM
31# The following ciphers may be excluded (by Configure). This means functions
32# defined with ifndef(NO_XXX) are not included in the .def file, and everything
33# in directory xxx is ignored.
34my $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
3009458e
RL
35my $no_cast;
36my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
0f583f69
UM
37my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0;
38
31ff97b2 39foreach (@ARGV, split(/ /, $options))
d02b48c6 40 {
06c68491
DSH
41 $W32=1 if $_ eq "32";
42 $W32=0 if $_ eq "16";
43 if($_ eq "NT") {
44 $W32 = 1;
45 $NT = 1;
46 }
d02b48c6 47 $do_ssl=1 if $_ eq "ssleay";
55a9cc6e 48 $do_ssl=1 if $_ eq "ssl";
d02b48c6 49 $do_crypto=1 if $_ eq "libeay";
55a9cc6e
DSH
50 $do_crypto=1 if $_ eq "crypto";
51 $do_update=1 if $_ eq "update";
12aefe78 52 $do_ctest=1 if $_ eq "ctest";
967f4ca8 53 $do_ctestall=1 if $_ eq "ctestall";
47339f61 54 $rsaref=1 if $_ eq "rsaref";
a8b07aa4 55 #$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK";
8cf65228
UM
56
57 if (/^no-rc2$/) { $no_rc2=1; }
58 elsif (/^no-rc4$/) { $no_rc4=1; }
59 elsif (/^no-rc5$/) { $no_rc5=1; }
60 elsif (/^no-idea$/) { $no_idea=1; }
61 elsif (/^no-des$/) { $no_des=1; }
62 elsif (/^no-bf$/) { $no_bf=1; }
63 elsif (/^no-cast$/) { $no_cast=1; }
64 elsif (/^no-md2$/) { $no_md2=1; }
3009458e 65 elsif (/^no-md4$/) { $no_md4=1; }
8cf65228
UM
66 elsif (/^no-md5$/) { $no_md5=1; }
67 elsif (/^no-sha$/) { $no_sha=1; }
68 elsif (/^no-ripemd$/) { $no_ripemd=1; }
69 elsif (/^no-mdc2$/) { $no_mdc2=1; }
70 elsif (/^no-rsa$/) { $no_rsa=1; }
71 elsif (/^no-dsa$/) { $no_dsa=1; }
72 elsif (/^no-dh$/) { $no_dh=1; }
73 elsif (/^no-hmac$/) { $no_hmac=1; }
d02b48c6
RE
74 }
75
12aefe78 76
d02b48c6
RE
77if (!$do_ssl && !$do_crypto)
78 {
47339f61 79 print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT ] [rsaref]\n";
d02b48c6
RE
80 exit(1);
81 }
82
83%ssl_list=&load_numbers($ssl_num);
55a9cc6e 84$max_ssl = $max_num;
d02b48c6 85%crypto_list=&load_numbers($crypto_num);
55a9cc6e 86$max_crypto = $max_num;
d02b48c6 87
0f583f69 88my $ssl="ssl/ssl.h";
d02b48c6 89
0f583f69 90my $crypto ="crypto/crypto.h";
8cf65228
UM
91$crypto.=" crypto/des/des.h" unless $no_des;
92$crypto.=" crypto/idea/idea.h" unless $no_idea;
93$crypto.=" crypto/rc4/rc4.h" unless $no_rc4;
94$crypto.=" crypto/rc5/rc5.h" unless $no_rc5;
95$crypto.=" crypto/rc2/rc2.h" unless $no_rc2;
96$crypto.=" crypto/bf/blowfish.h" unless $no_bf;
97$crypto.=" crypto/cast/cast.h" unless $no_cast;
98$crypto.=" crypto/md2/md2.h" unless $no_md2;
3009458e 99$crypto.=" crypto/md4/md4.h" unless $no_md4;
8cf65228
UM
100$crypto.=" crypto/md5/md5.h" unless $no_md5;
101$crypto.=" crypto/mdc2/mdc2.h" unless $no_mdc2;
102$crypto.=" crypto/sha/sha.h" unless $no_sha;
103$crypto.=" crypto/ripemd/ripemd.h" unless $no_ripemd;
d02b48c6
RE
104
105$crypto.=" crypto/bn/bn.h";
8cf65228
UM
106$crypto.=" crypto/rsa/rsa.h" unless $no_rsa;
107$crypto.=" crypto/dsa/dsa.h" unless $no_dsa;
108$crypto.=" crypto/dh/dh.h" unless $no_dh;
109$crypto.=" crypto/hmac/hmac.h" unless $no_hmac;
d02b48c6
RE
110
111$crypto.=" crypto/stack/stack.h";
112$crypto.=" crypto/buffer/buffer.h";
113$crypto.=" crypto/bio/bio.h";
c22e4b19 114$crypto.=" crypto/dso/dso.h";
d02b48c6
RE
115$crypto.=" crypto/lhash/lhash.h";
116$crypto.=" crypto/conf/conf.h";
117$crypto.=" crypto/txt_db/txt_db.h";
118
119$crypto.=" crypto/evp/evp.h";
120$crypto.=" crypto/objects/objects.h";
121$crypto.=" crypto/pem/pem.h";
122#$crypto.=" crypto/meth/meth.h";
123$crypto.=" crypto/asn1/asn1.h";
124$crypto.=" crypto/asn1/asn1_mac.h";
125$crypto.=" crypto/err/err.h";
126$crypto.=" crypto/pkcs7/pkcs7.h";
ee0508d4 127$crypto.=" crypto/pkcs12/pkcs12.h";
d02b48c6
RE
128$crypto.=" crypto/x509/x509.h";
129$crypto.=" crypto/x509/x509_vfy.h";
679ab7c3 130$crypto.=" crypto/x509v3/x509v3.h";
d02b48c6 131$crypto.=" crypto/rand/rand.h";
dfeab068
RE
132$crypto.=" crypto/comp/comp.h";
133$crypto.=" crypto/tmdiff.h";
d02b48c6 134
0f583f69
UM
135my @ssl_func = &do_defs("SSLEAY", $ssl);
136my @crypto_func = &do_defs("LIBEAY", $crypto);
55a9cc6e 137
47339f61 138
55a9cc6e
DSH
139if ($do_update) {
140
141if ($do_ssl == 1) {
142 open(OUT, ">>$ssl_num");
143 &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl, @ssl_func);
144 close OUT;
145}
146
147if($do_crypto == 1) {
148 open(OUT, ">>$crypto_num");
149 &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto, @crypto_func);
150 close OUT;
12aefe78
DSH
151}
152
967f4ca8 153} elsif ($do_ctest || $do_ctestall) {
12aefe78
DSH
154
155 print <<"EOF";
156
157/* Test file to check all DEF file symbols are present by trying
158 * to link to all of them. This is *not* intended to be run!
159 */
160
161int main()
162{
163EOF
967f4ca8 164 &print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_func)
12aefe78
DSH
165 if $do_ssl == 1;
166
967f4ca8 167 &print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_func)
12aefe78
DSH
168 if $do_crypto == 1;
169
170 print "}\n";
55a9cc6e
DSH
171
172} else {
8cf65228
UM
173
174 &print_def_file(*STDOUT,"SSLEAY",*ssl_list,@ssl_func)
55a9cc6e
DSH
175 if $do_ssl == 1;
176
8cf65228 177 &print_def_file(*STDOUT,"LIBEAY",*crypto_list,@crypto_func)
55a9cc6e 178 if $do_crypto == 1;
8cf65228 179
55a9cc6e 180}
d02b48c6 181
d02b48c6
RE
182
183sub do_defs
47339f61
DSH
184{
185 my($name,$files)=@_;
0f583f69 186 my $file;
47339f61
DSH
187 my @ret;
188 my %funcs;
0f583f69 189 my $cpp;
d02b48c6 190
d02b48c6
RE
191 foreach $file (split(/\s+/,$files))
192 {
d02b48c6 193 open(IN,"<$file") || die "unable to open $file:$!\n";
0f583f69 194 my $line = "", my $def= "";
47339f61
DSH
195 my %tag = (
196 FreeBSD => 0,
197 NOPROTO => 0,
198 WIN16 => 0,
199 PERL5 => 0,
200 _WINDLL => 0,
201 NO_FP_API => 0,
202 CONST_STRICT => 0,
203 TRUE => 1,
0f583f69
UM
204 NO_RC2 => 0,
205 NO_RC4 => 0,
206 NO_RC5 => 0,
207 NO_IDEA => 0,
208 NO_DES => 0,
209 NO_BF => 0,
210 NO_CAST => 0,
211 NO_MD2 => 0,
3009458e 212 NO_MD4 => 0,
0f583f69
UM
213 NO_MD5 => 0,
214 NO_SHA => 0,
215 NO_RIPEMD => 0,
216 NO_MDC2 => 0,
217 NO_RSA => 0,
218 NO_DSA => 0,
219 NO_DH => 0,
220 NO_HMAC => 0,
47339f61
DSH
221 );
222 while(<IN>) {
223 last if (/BEGIN ERROR CODES/);
224 if ($line ne '') {
225 $_ = $line . $_;
226 $line = '';
d02b48c6 227 }
47339f61
DSH
228
229 if (/\\$/) {
230 $line = $_;
231 next;
232 }
233
234 $cpp = 1 if /^#.*ifdef.*cplusplus/;
235 if ($cpp) {
236 $cpp = 0 if /^#.*endif/;
237 next;
238 }
239
240 s/\/\*.*?\*\///gs; # ignore comments
241 s/{[^{}]*}//gs; # ignore {} blocks
242 if (/^\#\s*ifndef (.*)/) {
d02b48c6
RE
243 push(@tag,$1);
244 $tag{$1}=-1;
245 next;
47339f61 246 } elsif (/^\#\s*if !defined\(([^\)]+)\)/) {
d02b48c6
RE
247 push(@tag,$1);
248 $tag{$1}=-1;
249 next;
47339f61 250 } elsif (/^\#\s*ifdef (.*)/) {
d02b48c6
RE
251 push(@tag,$1);
252 $tag{$1}=1;
253 next;
47339f61 254 } elsif (/^\#\s*if defined(.*)/) {
d02b48c6
RE
255 push(@tag,$1);
256 $tag{$1}=1;
257 next;
47339f61 258 } elsif (/^\#\s*endif/) {
d02b48c6
RE
259 $tag{$tag[$#tag]}=0;
260 pop(@tag);
261 next;
47339f61
DSH
262 } elsif (/^\#\s*else/) {
263 my $t=$tag[$#tag];
d02b48c6
RE
264 $tag{$t}= -$tag{$t};
265 next;
47339f61
DSH
266 } elsif (/^\#\s*if\s+1/) {
267 # Dummy tag
268 push(@tag,"TRUE");
269 $tag{"TRUE"}=1;
270 next;
1e414935
BM
271 } elsif (/^\#\s*if\s+0/) {
272 # Dummy tag
273 push(@tag,"TRUE");
274 $tag{"TRUE"}=-1;
275 next;
47339f61
DSH
276 } elsif (/^\#/) {
277 next;
278 }
13083215 279 if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
a8b07aa4 280 next;
13083215 281 } elsif (/^\s*DECLARE_ASN1_SET_OF\s*\(\s*(\w*)\s*\)/) {
a8b07aa4 282 next;
dbd665c2
DSH
283 } elsif (/^DECLARE_PEM_rw\s*\(\s*(\w*)\s*,/ ||
284 /^DECLARE_PEM_rw_cb\s*\(\s*(\w*)\s*,/ ) {
c22e4b19
UM
285 if (!($no_rsa && ($1 eq "RSAPrivateKey" ||
286 $1 eq "RSAPublicKey" ||
287 $1 eq "RSA_PUBKEY"))) {
288 if($W32) {
289 $funcs{"PEM_read_${1}"} = 1;
290 $funcs{"PEM_write_${1}"} = 1;
291 }
292 $funcs{"PEM_read_bio_${1}"} = 1;
293 $funcs{"PEM_write_bio_${1}"} = 1;
dbd665c2 294 }
8a208cba
DSH
295 } elsif (/^DECLARE_PEM_write\s*\(\s*(\w*)\s*,/ ||
296 /^DECLARE_PEM_write_cb\s*\(\s*(\w*)\s*,/ ) {
c22e4b19
UM
297 if (!($no_rsa && ($1 eq "RSAPrivateKey" ||
298 $1 eq "RSAPublicKey" ||
299 $1 eq "RSA_PUBKEY"))) {
300 if($W32) {
301 $funcs{"PEM_write_${1}"} = 1;
302 }
303 $funcs{"PEM_write_bio_${1}"} = 1;
8a208cba 304 }
8a208cba
DSH
305 } elsif (/^DECLARE_PEM_read\s*\(\s*(\w*)\s*,/ ||
306 /^DECLARE_PEM_read_cb\s*\(\s*(\w*)\s*,/ ) {
307 if($W32) {
308 $funcs{"PEM_read_${1}"} = 1;
309 }
310 $funcs{"PEM_read_bio_${1}"} = 1;
0f583f69 311 } elsif (
1e414935 312 ($tag{'TRUE'} != -1) &&
d02b48c6 313 ($tag{'FreeBSD'} != 1) &&
47339f61 314 ($tag{'CONST_STRICT'} != 1) &&
06c68491
DSH
315 (($W32 && ($tag{'WIN16'} != 1)) ||
316 (!$W32 && ($tag{'WIN16'} != -1))) &&
58964a49
RE
317 ($tag{'PERL5'} != 1) &&
318# ($tag{'_WINDLL'} != -1) &&
06c68491
DSH
319 ((!$W32 && $tag{'_WINDLL'} != -1) ||
320 ($W32 && $tag{'_WINDLL'} != 1)) &&
321 ((($tag{'NO_FP_API'} != 1) && $W32) ||
0f583f69
UM
322 (($tag{'NO_FP_API'} != -1) && !$W32)) &&
323 ($tag{'NO_RC2'} == 0 || !$no_rc2) &&
324 ($tag{'NO_RC4'} == 0 || !$no_rc4) &&
325 ($tag{'NO_RC5'} == 0 || !$no_rc5) &&
326 ($tag{'NO_IDEA'} == 0 || !$no_idea) &&
327 ($tag{'NO_DES'} == 0 || !$no_des) &&
328 ($tag{'NO_BF'} == 0 || !$no_bf) &&
329 ($tag{'NO_CAST'} == 0 || !$no_cast) &&
330 ($tag{'NO_MD2'} == 0 || !$no_md2) &&
3009458e 331 ($tag{'NO_MD4'} == 0 || !$no_md4) &&
0f583f69
UM
332 ($tag{'NO_MD5'} == 0 || !$no_md5) &&
333 ($tag{'NO_SHA'} == 0 || !$no_sha) &&
334 ($tag{'NO_RIPEMD'} == 0 || !$no_ripemd) &&
335 ($tag{'NO_MDC2'} == 0 || !$no_mdc2) &&
336 ($tag{'NO_RSA'} == 0 || !$no_rsa) &&
337 ($tag{'NO_DSA'} == 0 || !$no_dsa) &&
338 ($tag{'NO_DH'} == 0 || !$no_dh) &&
339 ($tag{'NO_HMAC'} == 0 || !$no_hmac))
d02b48c6 340 {
47339f61
DSH
341 if (/{|\/\*/) { # }
342 $line = $_;
343 } else {
344 $def .= $_;
345 }
d02b48c6
RE
346 }
347 }
348 close(IN);
47339f61
DSH
349
350 foreach (split /;/, $def) {
351 s/^[\n\s]*//g;
352 s/[\n\s]*$//g;
e41c8d6a 353 next if(/#define/);
47339f61 354 next if(/typedef\W/);
8cf65228
UM
355 next if(/EVP_bf/ and $no_bf);
356 next if(/EVP_cast/ and $no_cast);
357 next if(/EVP_des/ and $no_des);
358 next if(/EVP_dss/ and $no_dsa);
359 next if(/EVP_idea/ and $no_idea);
360 next if(/EVP_md2/ and $no_md2);
3009458e 361 next if(/EVP_md4/ and $no_md4);
8cf65228
UM
362 next if(/EVP_md5/ and $no_md5);
363 next if(/EVP_rc2/ and $no_rc2);
364 next if(/EVP_rc4/ and $no_rc4);
365 next if(/EVP_rc5/ and $no_rc5);
366 next if(/EVP_ripemd/ and $no_ripemd);
367 next if(/EVP_sha/ and $no_sha);
c22e4b19
UM
368 next if(/EVP_(Open|Seal)(Final|Init)/ and $no_rsa);
369 next if(/PEM_Seal(Final|Init|Update)/ and $no_rsa);
370 next if(/RSAPrivateKey/ and $no_rsa);
371 next if(/SSLv23?_((client|server)_)?method/ and $no_rsa);
372
47339f61
DSH
373 if (/\(\*(\w*)\([^\)]+/) {
374 $funcs{$1} = 1;
375 } elsif (/\w+\W+(\w+)\W*\(\s*\)$/s) {
376 # K&R C
377 next;
378 } elsif (/\w+\W+\w+\W*\(.*\)$/s) {
379 while (not /\(\)$/s) {
380 s/[^\(\)]*\)$/\)/s;
381 s/\([^\(\)]*\)\)$/\)/s;
382 }
383 s/\(void\)//;
384 /(\w+)\W*\(\)/s;
385 $funcs{$1} = 1;
386 } elsif (/\(/ and not (/=/)) {
387 print STDERR "File $file: cannot parse: $_;\n";
388 }
d02b48c6 389 }
d02b48c6
RE
390 }
391
47339f61
DSH
392 # Prune the returned functions
393
394 delete $funcs{"SSL_add_dir_cert_subjects_to_stack"};
47339f61 395 delete $funcs{"RSA_PKCS1_RSAref"} unless $rsaref;
9b95f1df 396 delete $funcs{"bn_dump1"};
47339f61
DSH
397
398 if($W32) {
399 delete $funcs{"BIO_s_file_internal"};
400 delete $funcs{"BIO_new_file_internal"};
401 delete $funcs{"BIO_new_fp_internal"};
402 } else {
403 if(exists $funcs{"ERR_load_CRYPTO_strings"}) {
404 delete $funcs{"ERR_load_CRYPTO_strings"};
405 $funcs{"ERR_load_CRYPTOlib_strings"} = 1;
d02b48c6 406 }
47339f61
DSH
407 delete $funcs{"BIO_s_file"};
408 delete $funcs{"BIO_new_file"};
409 delete $funcs{"BIO_new_fp"};
410 }
411 if (!$NT) {
412 delete $funcs{"BIO_s_log"};
d02b48c6
RE
413 }
414
47339f61 415 push @ret, keys %funcs;
d02b48c6 416
47339f61
DSH
417 return(@ret);
418}
d02b48c6 419
12aefe78
DSH
420sub print_test_file
421{
967f4ca8 422 (*OUT,my $name,*nums,my $all,my @functions)=@_;
0f583f69 423 my $n = 1; my @e; my @r;
967f4ca8 424 my $func; my $prev = "";
12aefe78 425
967f4ca8 426 push(@functions, keys %nums) if $all;
12aefe78
DSH
427 (@e)=grep(/^SSLeay/,@functions);
428 (@r)=grep(!/^SSLeay/,@functions);
429 @functions=((sort @e),(sort @r));
430
431 foreach $func (@functions) {
967f4ca8
RL
432 if ($func ne $prev) {
433 if (!defined($nums{$func})) {
434 printf STDERR "$func does not have a number assigned\n"
435 if(!$do_update);
436 } else {
437 $n=$nums{$func};
438 print OUT "\t$func();\n";
439 }
12aefe78 440 }
967f4ca8 441 $prev = $func; # To avoid duplicates...
12aefe78
DSH
442 }
443}
444
d02b48c6 445sub print_def_file
47339f61 446{
0f583f69
UM
447 (*OUT,my $name,*nums,my @functions)=@_;
448 my $n = 1; my @e; my @r;
d02b48c6 449
06c68491 450 if ($W32)
d02b48c6
RE
451 { $name.="32"; }
452 else
453 { $name.="16"; }
454
455 print OUT <<"EOF";
456;
9b3086fe 457; Definition file for the DLL version of the $name library from OpenSSL
d02b48c6
RE
458;
459
460LIBRARY $name
461
9b3086fe 462DESCRIPTION 'OpenSSL $name - http://www.openssl.org/'
d02b48c6
RE
463
464EOF
465
47339f61 466 if (!$W32) {
d02b48c6
RE
467 print <<"EOF";
468CODE PRELOAD MOVEABLE
469DATA PRELOAD MOVEABLE SINGLE
470
471EXETYPE WINDOWS
472
473HEAPSIZE 4096
474STACKSIZE 8192
475
476EOF
47339f61 477 }
d02b48c6
RE
478
479 print "EXPORTS\n";
480
481
482 (@e)=grep(/^SSLeay/,@functions);
483 (@r)=grep(!/^SSLeay/,@functions);
484 @functions=((sort @e),(sort @r));
485
47339f61
DSH
486 foreach $func (@functions) {
487 if (!defined($nums{$func})) {
8cf65228
UM
488 printf STDERR "$func does not have a number assigned\n"
489 if(!$do_update);
47339f61 490 } else {
d02b48c6 491 $n=$nums{$func};
06c68491 492 printf OUT " %s%-40s@%d\n",($W32)?"":"_",$func,$n;
d02b48c6 493 }
d02b48c6 494 }
47339f61
DSH
495 printf OUT "\n";
496}
d02b48c6
RE
497
498sub load_numbers
47339f61
DSH
499{
500 my($name)=@_;
501 my(@a,%ret);
d02b48c6 502
55a9cc6e
DSH
503 $max_num = 0;
504
d02b48c6 505 open(IN,"<$name") || die "unable to open $name:$!\n";
47339f61 506 while (<IN>) {
d02b48c6
RE
507 chop;
508 s/#.*$//;
509 next if /^\s*$/;
510 @a=split;
511 $ret{$a[0]}=$a[1];
55a9cc6e 512 $max_num = $a[1] if $a[1] > $max_num;
47339f61 513 }
d02b48c6
RE
514 close(IN);
515 return(%ret);
47339f61 516}
55a9cc6e
DSH
517
518sub update_numbers
47339f61
DSH
519{
520 (*OUT,$name,*nums,my $start_num, my @functions)=@_;
55a9cc6e
DSH
521 my $new_funcs = 0;
522 print STDERR "Updating $name\n";
47339f61
DSH
523 foreach $func (@functions) {
524 if (!exists $nums{$func}) {
55a9cc6e
DSH
525 $new_funcs++;
526 printf OUT "%s%-40s%d\n","",$func, ++$start_num;
55a9cc6e 527 }
47339f61 528 }
55a9cc6e
DSH
529 if($new_funcs) {
530 print STDERR "$new_funcs New Functions added\n";
531 } else {
532 print STDERR "No New Functions Added\n";
533 }
47339f61 534}