(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/util/mkdef.pl

    1: #!/usr/local/bin/perl -w
    2: #
    3: # generate a .def file
    4: #
    5: # It does this by parsing the header files and looking for the
    6: # prototyped functions: it then prunes the output.
    7: #
    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
   40: #   symbol name variants for platforms where the names are too long for the
   41: #   compiler or linker, or if the systems is case insensitive and there is a
   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
   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
   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.
   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: #
   56: 
   57: my $debug=0;
   58: 
   59: my $crypto_num= "util/libeay.num";
   60: my $ssl_num=    "util/ssleay.num";
   61: my $libname;
   62: 
   63: my $do_update = 0;
   64: my $do_rewrite = 1;
   65: my $do_crypto = 0;
   66: my $do_ssl = 0;
   67: my $do_ctest = 0;
   68: my $do_ctestall = 0;
   69: my $do_checkexist = 0;
   70: 
   71: my $VMSVAX=0;
   72: my $VMSAlpha=0;
   73: my $VMS=0;
   74: my $W32=0;
   75: my $W16=0;
   76: my $NT=0;
   77: my $OS2=0;
   78: # Set this to make typesafe STACK definitions appear in DEF
   79: my $safe_stack_def = 0;
   80: 
   81: my @known_platforms = ( "__FreeBSD__", "PERL5", "NeXT",
   82:                         "EXPORT_VAR_AS_FUNCTION" );
   83: my @known_ossl_platforms = ( "VMS", "WIN16", "WIN32", "WINNT", "OS2" );
   84: my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
   85:                          "CAST", "MD2", "MD4", "MD5", "SHA", "SHA0", "SHA1",
   86:                          "SHA256", "SHA512", "RIPEMD",
   87:                          "MDC2", "RSA", "DSA", "DH", "EC", "ECDH", "ECDSA", "HMAC", "AES", "CAMELLIA", "SEED",
   88:                          # Envelope "algorithms"
   89:                          "EVP", "X509", "ASN1_TYPEDEFS",
   90:                          # Helper "algorithms"
   91:                          "BIO", "COMP", "BUFFER", "LHASH", "STACK", "ERR",
   92:                          "LOCKING",
   93:                          # External "algorithms"
   94:                          "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
   95:                          # Engines
   96:                          "STATIC_ENGINE", "ENGINE", "HW", "GMP",
   97:                          # RFC3779 support 
   98:                          "RFC3779",
   99:                          # TLS extension support
  100:                          "TLSEXT",
  101:                          # Deprecated functions
  102:                          "DEPRECATED" );
  103: 
  104: my $options="";
  105: open(IN,"<Makefile") || die "unable to open Makefile!\n";
  106: while(<IN>) {
  107:     $options=$1 if (/^OPTIONS=(.*)$/);
  108: }
  109: close(IN);
  110: 
  111: # The following ciphers may be excluded (by Configure). This means functions
  112: # defined with ifndef(NO_XXX) are not included in the .def file, and everything
  113: # in directory xxx is ignored.
  114: my $no_rc2; my $no_rc4; my $no_rc5; my $no_idea; my $no_des; my $no_bf;
  115: my $no_cast;
  116: my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
  117: my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
  118: my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw; my $no_camellia;
  119: my $no_seed;
  120: my $no_fp_api; my $no_static_engine; my $no_gmp; my $no_deprecated;
  121: my $no_rfc3779; my $no_tlsext;
  122: 
  123: 
  124: foreach (@ARGV, split(/ /, $options))
  125:         {
  126:         $debug=1 if $_ eq "debug";
  127:         $W32=1 if $_ eq "32";
  128:         $W16=1 if $_ eq "16";
  129:         if($_ eq "NT") {
  130:                 $W32 = 1;
  131:                 $NT = 1;
  132:         }
  133:         if ($_ eq "VMS-VAX") {
  134:                 $VMS=1;
  135:                 $VMSVAX=1;
  136:         }
  137:         if ($_ eq "VMS-Alpha") {
  138:                 $VMS=1;
  139:                 $VMSAlpha=1;
  140:         }
  141:         $VMS=1 if $_ eq "VMS";
  142:         $OS2=1 if $_ eq "OS2";
  143: 
  144:         $do_ssl=1 if $_ eq "ssleay";
  145:         if ($_ eq "ssl") {
  146:                 $do_ssl=1; 
  147:                 $libname=$_
  148:         }
  149:         $do_crypto=1 if $_ eq "libeay";
  150:         if ($_ eq "crypto") {
  151:                 $do_crypto=1;
  152:                 $libname=$_;
  153:         }
  154:         $no_static_engine=1 if $_ eq "no-static-engine";
  155:         $no_static_engine=0 if $_ eq "enable-static-engine";
  156:         $do_update=1 if $_ eq "update";
  157:         $do_rewrite=1 if $_ eq "rewrite";
  158:         $do_ctest=1 if $_ eq "ctest";
  159:         $do_ctestall=1 if $_ eq "ctestall";
  160:         $do_checkexist=1 if $_ eq "exist";
  161:         #$safe_stack_def=1 if $_ eq "-DDEBUG_SAFESTACK";
  162: 
  163:         if    (/^no-rc2$/)      { $no_rc2=1; }
  164:         elsif (/^no-rc4$/)      { $no_rc4=1; }
  165:         elsif (/^no-rc5$/)      { $no_rc5=1; }
  166:         elsif (/^no-idea$/)     { $no_idea=1; }
  167:         elsif (/^no-des$/)      { $no_des=1; $no_mdc2=1; }
  168:         elsif (/^no-bf$/)       { $no_bf=1; }
  169:         elsif (/^no-cast$/)     { $no_cast=1; }
  170:         elsif (/^no-md2$/)      { $no_md2=1; }
  171:         elsif (/^no-md4$/)      { $no_md4=1; }
  172:         elsif (/^no-md5$/)      { $no_md5=1; }
  173:         elsif (/^no-sha$/)      { $no_sha=1; }
  174:         elsif (/^no-ripemd$/)   { $no_ripemd=1; }
  175:         elsif (/^no-mdc2$/)     { $no_mdc2=1; }
  176:         elsif (/^no-rsa$/)      { $no_rsa=1; }
  177:         elsif (/^no-dsa$/)      { $no_dsa=1; }
  178:         elsif (/^no-dh$/)       { $no_dh=1; }
  179:         elsif (/^no-ec$/)       { $no_ec=1; }
  180:         elsif (/^no-ecdsa$/)   { $no_ecdsa=1; }
  181:         elsif (/^no-ecdh$/)    { $no_ecdh=1; }
  182:         elsif (/^no-hmac$/)    { $no_hmac=1; }
  183:         elsif (/^no-aes$/)     { $no_aes=1; }
  184:         elsif (/^no-camellia$/)        { $no_camellia=1; }
  185:         elsif (/^no-seed$/)     { $no_seed=1; }
  186:         elsif (/^no-evp$/)     { $no_evp=1; }
  187:         elsif (/^no-lhash$/)   { $no_lhash=1; }
  188:         elsif (/^no-stack$/)   { $no_stack=1; }
  189:         elsif (/^no-err$/)     { $no_err=1; }
  190:         elsif (/^no-buffer$/)  { $no_buffer=1; }
  191:         elsif (/^no-bio$/)     { $no_bio=1; }
  192:         #elsif (/^no-locking$/)        { $no_locking=1; }
  193:         elsif (/^no-comp$/)    { $no_comp=1; }
  194:         elsif (/^no-dso$/)     { $no_dso=1; }
  195:         elsif (/^no-krb5$/)    { $no_krb5=1; }
  196:         elsif (/^no-engine$/)  { $no_engine=1; }
  197:         elsif (/^no-hw$/)      { $no_hw=1; }
  198:         elsif (/^no-gmp$/)     { $no_gmp=1; }
  199:         elsif (/^no-rfc3779$/) { $no_rfc3779=1; }
  200:         elsif (/^no-tlsext$/)  { $no_tlsext=1; }
  201:         }
  202: 
  203: 
  204: if (!$libname) { 
  205:         if ($do_ssl) {
  206:                 $libname="SSLEAY";
  207:         }
  208:         if ($do_crypto) {
  209:                 $libname="LIBEAY";
  210:         }
  211: }
  212: 
  213: # If no platform is given, assume WIN32
  214: if ($W32 + $W16 + $VMS + $OS2 == 0) {
  215:         $W32 = 1;
  216: }
  217: 
  218: # Add extra knowledge
  219: if ($W16) {
  220:         $no_fp_api=1;
  221: }
  222: 
  223: if (!$do_ssl && !$do_crypto)
  224:         {
  225:         print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 | NT | OS2 ]\n";
  226:         exit(1);
  227:         }
  228: 
  229: %ssl_list=&load_numbers($ssl_num);
  230: $max_ssl = $max_num;
  231: %crypto_list=&load_numbers($crypto_num);
  232: $max_crypto = $max_num;
  233: 
  234: my $ssl="ssl/ssl.h";
  235: $ssl.=" ssl/kssl.h";
  236: $ssl.=" ssl/tls1.h";
  237: 
  238: my $crypto ="crypto/crypto.h";
  239: $crypto.=" crypto/o_dir.h";
  240: $crypto.=" crypto/des/des.h crypto/des/des_old.h" ; # unless $no_des;
  241: $crypto.=" crypto/idea/idea.h" ; # unless $no_idea;
  242: $crypto.=" crypto/rc4/rc4.h" ; # unless $no_rc4;
  243: $crypto.=" crypto/rc5/rc5.h" ; # unless $no_rc5;
  244: $crypto.=" crypto/rc2/rc2.h" ; # unless $no_rc2;
  245: $crypto.=" crypto/bf/blowfish.h" ; # unless $no_bf;
  246: $crypto.=" crypto/cast/cast.h" ; # unless $no_cast;
  247: $crypto.=" crypto/md2/md2.h" ; # unless $no_md2;
  248: $crypto.=" crypto/md4/md4.h" ; # unless $no_md4;
  249: $crypto.=" crypto/md5/md5.h" ; # unless $no_md5;
  250: $crypto.=" crypto/mdc2/mdc2.h" ; # unless $no_mdc2;
  251: $crypto.=" crypto/sha/sha.h" ; # unless $no_sha;
  252: $crypto.=" crypto/ripemd/ripemd.h" ; # unless $no_ripemd;
  253: $crypto.=" crypto/aes/aes.h" ; # unless $no_aes;
  254: $crypto.=" crypto/camellia/camellia.h" ; # unless $no_camellia;
  255: $crypto.=" crypto/seed/seed.h"; # unless $no_seed;
  256: 
  257: $crypto.=" crypto/bn/bn.h";
  258: $crypto.=" crypto/rsa/rsa.h" ; # unless $no_rsa;
  259: $crypto.=" crypto/dsa/dsa.h" ; # unless $no_dsa;
  260: $crypto.=" crypto/dh/dh.h" ; # unless $no_dh;
  261: $crypto.=" crypto/ec/ec.h" ; # unless $no_ec;
  262: $crypto.=" crypto/ecdsa/ecdsa.h" ; # unless $no_ecdsa;
  263: $crypto.=" crypto/ecdh/ecdh.h" ; # unless $no_ecdh;
  264: $crypto.=" crypto/hmac/hmac.h" ; # unless $no_hmac;
  265: 
  266: $crypto.=" crypto/engine/engine.h"; # unless $no_engine;
  267: $crypto.=" crypto/stack/stack.h" ; # unless $no_stack;
  268: $crypto.=" crypto/buffer/buffer.h" ; # unless $no_buffer;
  269: $crypto.=" crypto/bio/bio.h" ; # unless $no_bio;
  270: $crypto.=" crypto/dso/dso.h" ; # unless $no_dso;
  271: $crypto.=" crypto/lhash/lhash.h" ; # unless $no_lhash;
  272: $crypto.=" crypto/conf/conf.h";
  273: $crypto.=" crypto/txt_db/txt_db.h";
  274: 
  275: $crypto.=" crypto/evp/evp.h" ; # unless $no_evp;
  276: $crypto.=" crypto/objects/objects.h";
  277: $crypto.=" crypto/pem/pem.h";
  278: #$crypto.=" crypto/meth/meth.h";
  279: $crypto.=" crypto/asn1/asn1.h";
  280: $crypto.=" crypto/asn1/asn1t.h";
  281: $crypto.=" crypto/asn1/asn1_mac.h";
  282: $crypto.=" crypto/err/err.h" ; # unless $no_err;
  283: $crypto.=" crypto/pkcs7/pkcs7.h";
  284: $crypto.=" crypto/pkcs12/pkcs12.h";
  285: $crypto.=" crypto/x509/x509.h";
  286: $crypto.=" crypto/x509/x509_vfy.h";
  287: $crypto.=" crypto/x509v3/x509v3.h";
  288: $crypto.=" crypto/rand/rand.h";
  289: $crypto.=" crypto/comp/comp.h" ; # unless $no_comp;
  290: $crypto.=" crypto/ocsp/ocsp.h";
  291: $crypto.=" crypto/ui/ui.h crypto/ui/ui_compat.h";
  292: $crypto.=" crypto/krb5/krb5_asn.h";
  293: $crypto.=" crypto/tmdiff.h";
  294: $crypto.=" crypto/store/store.h";
  295: $crypto.=" crypto/pqueue/pqueue.h";
  296: 
  297: my $symhacks="crypto/symhacks.h";
  298: 
  299: my @ssl_symbols = &do_defs("SSLEAY", $ssl, $symhacks);
  300: my @crypto_symbols = &do_defs("LIBEAY", $crypto, $symhacks);
  301: 
  302: if ($do_update) {
  303: 
  304: if ($do_ssl == 1) {
  305: 
  306:         &maybe_add_info("SSLEAY",*ssl_list,@ssl_symbols);
  307:         if ($do_rewrite == 1) {
  308:                 open(OUT, ">$ssl_num");
  309:                 &rewrite_numbers(*OUT,"SSLEAY",*ssl_list,@ssl_symbols);
  310:         } else {
  311:                 open(OUT, ">>$ssl_num");
  312:         }
  313:         &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl,@ssl_symbols);
  314:         close OUT;
  315: }
  316: 
  317: if($do_crypto == 1) {
  318: 
  319:         &maybe_add_info("LIBEAY",*crypto_list,@crypto_symbols);
  320:         if ($do_rewrite == 1) {
  321:                 open(OUT, ">$crypto_num");
  322:                 &rewrite_numbers(*OUT,"LIBEAY",*crypto_list,@crypto_symbols);
  323:         } else {
  324:                 open(OUT, ">>$crypto_num");
  325:         }
  326:         &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto,@crypto_symbols);
  327:         close OUT;
  328: } 
  329: 
  330: } elsif ($do_checkexist) {
  331:         &check_existing(*ssl_list, @ssl_symbols)
  332:                 if $do_ssl == 1;
  333:         &check_existing(*crypto_list, @crypto_symbols)
  334:                 if $do_crypto == 1;
  335: } elsif ($do_ctest || $do_ctestall) {
  336: 
  337:         print <<"EOF";
  338: 
  339: /* Test file to check all DEF file symbols are present by trying
  340:  * to link to all of them. This is *not* intended to be run!
  341:  */
  342: 
  343: int main()
  344: {
  345: EOF
  346:         &print_test_file(*STDOUT,"SSLEAY",*ssl_list,$do_ctestall,@ssl_symbols)
  347:                 if $do_ssl == 1;
  348: 
  349:         &print_test_file(*STDOUT,"LIBEAY",*crypto_list,$do_ctestall,@crypto_symbols)
  350:                 if $do_crypto == 1;
  351: 
  352:         print "}\n";
  353: 
  354: } else {
  355: 
  356:         &print_def_file(*STDOUT,$libname,*ssl_list,@ssl_symbols)
  357:                 if $do_ssl == 1;
  358: 
  359:         &print_def_file(*STDOUT,$libname,*crypto_list,@crypto_symbols)
  360:                 if $do_crypto == 1;
  361: 
  362: }
  363: 
  364: 
  365: sub do_defs
  366: {
  367:         my($name,$files,$symhacksfile)=@_;
  368:         my $file;
  369:         my @ret;
  370:         my %syms;
  371:         my %platform;          # For anything undefined, we assume ""
  372:         my %kind;              # For anything undefined, we assume "FUNCTION"
  373:         my %algorithm;         # For anything undefined, we assume ""
  374:         my %variant;
  375:         my %variant_cnt;       # To be able to allocate "name{n}" if "name"
  376:                                 # is the same name as the original.
  377:         my $cpp;
  378:         my %unknown_algorithms = ();
  379: 
  380:         foreach $file (split(/\s+/,$symhacksfile." ".$files))
  381:                 {
  382:                 print STDERR "DEBUG: starting on $file:\n" if $debug;
  383:                 open(IN,"<$file") || die "unable to open $file:$!\n";
  384:                 my $line = "", my $def= "";
  385:                 my %tag = (
  386:                         (map { $_ => 0 } @known_platforms),
  387:                         (map { "OPENSSL_SYS_".$_ => 0 } @known_ossl_platforms),
  388:                         (map { "OPENSSL_NO_".$_ => 0 } @known_algorithms),
  389:                         NOPROTO              => 0,
  390:                         PERL5                => 0,
  391:                         _WINDLL              => 0,
  392:                         CONST_STRICT => 0,
  393:                         TRUE         => 1,
  394:                 );
  395:                 my $symhacking = $file eq $symhacksfile;
  396:                 my @current_platforms = ();
  397:                 my @current_algorithms = ();
  398: 
  399:                 # params: symbol, alias, platforms, kind
  400:                 # The reason to put this subroutine in a variable is that
  401:                 # it will otherwise create it's own, unshared, version of
  402:                 # %tag and %variant...
  403:                 my $make_variant = sub
  404:                 {
  405:                         my ($s, $a, $p, $k) = @_;
  406:                         my ($a1, $a2);
  407: 
  408:                         print STDERR "DEBUG: make_variant: Entered with ",$s,", ",$a,", ",(defined($p)?$p:""),", ",(defined($k)?$k:""),"\n" if $debug;
  409:                         if (defined($p))
  410:                         {
  411:                                 $a1 = join(",",$p,
  412:                                            grep(!/^$/,
  413:                                                 map { $tag{$_} == 1 ? $_ : "" }
  414:                                                 @known_platforms));
  415:                         }
  416:                         else
  417:                         {
  418:                                 $a1 = join(",",
  419:                                            grep(!/^$/,
  420:                                                 map { $tag{$_} == 1 ? $_ : "" }
  421:                                                 @known_platforms));
  422:                         }
  423:                         $a2 = join(",",
  424:                                    grep(!/^$/,
  425:                                         map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ : "" }
  426:                                         @known_ossl_platforms));
  427:                         print STDERR "DEBUG: make_variant: a1 = $a1; a2 = $a2\n" if $debug;
  428:                         if ($a1 eq "") { $a1 = $a2; }
  429:                         elsif ($a1 ne "" && $a2 ne "") { $a1 .= ",".$a2; }
  430:                         if ($a eq $s)
  431:                         {
  432:                                 if (!defined($variant_cnt{$s}))
  433:                                 {
  434:                                         $variant_cnt{$s} = 0;
  435:                                 }
  436:                                 $variant_cnt{$s}++;
  437:                                 $a .= "{$variant_cnt{$s}}";
  438:                         }
  439:                         my $toadd = $a.":".$a1.(defined($k)?":".$k:"");
  440:                         my $togrep = $s.'(\{[0-9]+\})?:'.$a1.(defined($k)?":".$k:"");
  441:                         if (!grep(/^$togrep$/,
  442:                                   split(/;/, defined($variant{$s})?$variant{$s}:""))) {
  443:                                 if (defined($variant{$s})) { $variant{$s} .= ";"; }
  444:                                 $variant{$s} .= $toadd;
  445:                         }
  446:                         print STDERR "DEBUG: make_variant: Exit with variant of ",$s," = ",$variant{$s},"\n" if $debug;
  447:                 };
  448: 
  449:                 print STDERR "DEBUG: parsing ----------\n" if $debug;
  450:                 while(<IN>) {
  451:                         if (/\/\* Error codes for the \w+ functions\. \*\//)
  452:                                 {
  453:                                 undef @tag;
  454:                                 last;
  455:                                 }
  456:                         if ($line ne '') {
  457:                                 $_ = $line . $_;
  458:                                 $line = '';
  459:                         }
  460: 
  461:                         if (/\\$/) {
  462:                                 chomp; # remove eol
  463:                                 chop; # remove ending backslash
  464:                                 $line = $_;
  465:                                 next;
  466:                         }
  467: 
  468:                         if(/\/\*/) {
  469:                                 if (not /\*\//) {   # multiline comment...
  470:                                         $line = $_;        # ... just accumulate
  471:                                         next;
  472:                                 } else {
  473:                                         s/\/\*.*?\*\///gs;# wipe it
  474:                                 }
  475:                         }
  476: 
  477:                         if ($cpp) {
  478:                                 $cpp++ if /^#\s*if/;
  479:                                 $cpp-- if /^#\s*endif/;
  480:                                 next;
  481:                        }
  482:                         $cpp = 1 if /^#.*ifdef.*cplusplus/;
  483: 
  484:                         s/{[^{}]*}//gs;                      # ignore {} blocks
  485:                         print STDERR "DEBUG: \$def=\"$def\"\n" if $debug && $def ne "";
  486:                         print STDERR "DEBUG: \$_=\"$_\"\n" if $debug;
  487:                         if (/^\#\s*ifndef\s+(.*)/) {
  488:                                 push(@tag,"-");
  489:                                 push(@tag,$1);
  490:                                 $tag{$1}=-1;
  491:                                 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
  492:                         } elsif (/^\#\s*if\s+!defined\(([^\)]+)\)/) {
  493:                                 push(@tag,"-");
  494:                                 if (/^\#\s*if\s+(!defined\(([^\)]+)\)(\s+\&\&\s+!defined\(([^\)]+)\))*)$/) {
  495:                                         my $tmp_1 = $1;
  496:                                         my $tmp_;
  497:                                         foreach $tmp_ (split '\&\&',$tmp_1) {
  498:                                                 $tmp_ =~ /!defined\(([^\)]+)\)/;
  499:                                                 print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
  500:                                                 push(@tag,$1);
  501:                                                 $tag{$1}=-1;
  502:                                         }
  503:                                 } else {
  504:                                         print STDERR "Warning: $file: complicated expression: $_" if $debug; # because it is O...
  505:                                         print STDERR "DEBUG: $file: found tag $1 = -1\n" if $debug;
  506:                                         push(@tag,$1);
  507:                                         $tag{$1}=-1;
  508:                                 }
  509:                         } elsif (/^\#\s*ifdef\s+(\S*)/) {
  510:                                 push(@tag,"-");
  511:                                 push(@tag,$1);
  512:                                 $tag{$1}=1;
  513:                                 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
  514:                         } elsif (/^\#\s*if\s+defined\(([^\)]+)\)/) {
  515:                                 push(@tag,"-");
  516:                                 if (/^\#\s*if\s+(defined\(([^\)]+)\)(\s+\|\|\s+defined\(([^\)]+)\))*)$/) {
  517:                                         my $tmp_1 = $1;
  518:                                         my $tmp_;
  519:                                         foreach $tmp_ (split '\|\|',$tmp_1) {
  520:                                                 $tmp_ =~ /defined\(([^\)]+)\)/;
  521:                                                 print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
  522:                                                 push(@tag,$1);
  523:                                                 $tag{$1}=1;
  524:                                         }
  525:                                 } else {
  526:                                         print STDERR "Warning: $file: complicated expression: $_\n" if $debug; # because it is O...
  527:                                         print STDERR "DEBUG: $file: found tag $1 = 1\n" if $debug;
  528:                                         push(@tag,$1);
  529:                                         $tag{$1}=1;
  530:                                 }
  531:                         } elsif (/^\#\s*error\s+(\w+) is disabled\./) {
  532:                                 my $tag_i = $#tag;
  533:                                 while($tag[$tag_i] ne "-") {
  534:                                         if ($tag[$tag_i] eq "OPENSSL_NO_".$1) {
  535:                                                 $tag{$tag[$tag_i]}=2;
  536:                                                 print STDERR "DEBUG: $file: chaged tag $1 = 2\n" if $debug;
  537:                                         }
  538:                                         $tag_i--;
  539:                                 }
  540:                         } elsif (/^\#\s*endif/) {
  541:                                 my $tag_i = $#tag;
  542:                                 while($tag_i > 0 && $tag[$tag_i] ne "-") {
  543:                                         my $t=$tag[$tag_i];
  544:                                         print STDERR "DEBUG: \$t=\"$t\"\n" if $debug;
  545:                                         if ($tag{$t}==2) {
  546:                                                 $tag{$t}=-1;
  547:                                         } else {
  548:                                                 $tag{$t}=0;
  549:                                         }
  550:                                         print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
  551:                                         pop(@tag);
  552:                                         if ($t =~ /^OPENSSL_NO_([A-Z0-9_]+)$/) {
  553:                                                 $t=$1;
  554:                                         } else {
  555:                                                 $t="";
  556:                                         }
  557:                                         if ($t ne ""
  558:                                             && !grep(/^$t$/, @known_algorithms)) {
  559:                                                 $unknown_algorithms{$t} = 1;
  560:                                                 #print STDERR "DEBUG: Added as unknown algorithm: $t\n" if $debug;
  561:                                         }
  562:                                         $tag_i--;
  563:                                 }
  564:                                 pop(@tag);
  565:                         } elsif (/^\#\s*else/) {
  566:                                 my $tag_i = $#tag;
  567:                                 while($tag[$tag_i] ne "-") {
  568:                                         my $t=$tag[$tag_i];
  569:                                         $tag{$t}= -$tag{$t};
  570:                                         print STDERR "DEBUG: $file: changed tag ",$t," = ",$tag{$t},"\n" if $debug;
  571:                                         $tag_i--;
  572:                                 }
  573:                         } elsif (/^\#\s*if\s+1/) {
  574:                                 push(@tag,"-");
  575:                                 # Dummy tag
  576:                                 push(@tag,"TRUE");
  577:                                 $tag{"TRUE"}=1;
  578:                                 print STDERR "DEBUG: $file: found 1\n" if $debug;
  579:                         } elsif (/^\#\s*if\s+0/) {
  580:                                 push(@tag,"-");
  581:                                 # Dummy tag
  582:                                 push(@tag,"TRUE");
  583:                                 $tag{"TRUE"}=-1;
  584:                                 print STDERR "DEBUG: $file: found 0\n" if $debug;
  585:                         } elsif (/^\#\s*define\s+(\w+)\s+(\w+)/
  586:                                  && $symhacking && $tag{'TRUE'} != -1) {
  587:                                 # This is for aliasing.  When we find an alias,
  588:                                 # we have to invert
  589:                                 &$make_variant($1,$2);
  590:                                 print STDERR "DEBUG: $file: defined $1 = $2\n" if $debug;
  591:                         }
  592:                         if (/^\#/) {
  593:                                 @current_platforms =
  594:                                     grep(!/^$/,
  595:                                          map { $tag{$_} == 1 ? $_ :
  596:                                                    $tag{$_} == -1 ? "!".$_  : "" }
  597:                                          @known_platforms);
  598:                                 push @current_platforms
  599:                                     , grep(!/^$/,
  600:                                            map { $tag{"OPENSSL_SYS_".$_} == 1 ? $_ :
  601:                                                      $tag{"OPENSSL_SYS_".$_} == -1 ? "!".$_  : "" }
  602:                                            @known_ossl_platforms);
  603:                                 @current_algorithms =
  604:                                     grep(!/^$/,
  605:                                          map { $tag{"OPENSSL_NO_".$_} == -1 ? $_ : "" }
  606:                                          @known_algorithms);
  607:                                 $def .=
  608:                                     "#INFO:"
  609:                                         .join(',',@current_platforms).":"
  610:                                             .join(',',@current_algorithms).";";
  611:                                 next;
  612:                         }
  613:                         if ($tag{'TRUE'} != -1) {
  614:                                 if (/^\s*DECLARE_STACK_OF\s*\(\s*(\w*)\s*\)/) {
  615:                                         next;
  616:                                 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
  617:                                         $def .= "int d2i_$3(void);";
  618:                                         $def .= "int i2d_$3(void);";
  619:                                         # Variant for platforms that do not
  620:                                         # have to access globale variables
  621:                                         # in shared libraries through functions
  622:                                         $def .=
  623:                                             "#INFO:"
  624:                                                 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
  625:                                                     .join(',',@current_algorithms).";";
  626:                                         $def .= "OPENSSL_EXTERN int $2_it;";
  627:                                         $def .=
  628:                                             "#INFO:"
  629:                                                 .join(',',@current_platforms).":"
  630:                                                     .join(',',@current_algorithms).";";
  631:                                         # Variant for platforms that have to
  632:                                         # access globale variables in shared
  633:                                         # libraries through functions
  634:                                         &$make_variant("$2_it","$2_it",
  635:                                                       "EXPORT_VAR_AS_FUNCTION",
  636:                                                       "FUNCTION");
  637:                                         next;
  638:                                 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_fname\s*\(\s*(\w*)\s*,\s*(\w*)\s*,\s*(\w*)\s*\)/) {
  639:                                         $def .= "int d2i_$3(void);";
  640:                                         $def .= "int i2d_$3(void);";
  641:                                         $def .= "int $3_free(void);";
  642:                                         $def .= "int $3_new(void);";
  643:                                         # Variant for platforms that do not
  644:                                         # have to access globale variables
  645:                                         # in shared libraries through functions
  646:                                         $def .=
  647:                                             "#INFO:"
  648:                                                 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
  649:                                                     .join(',',@current_algorithms).";";
  650:                                         $def .= "OPENSSL_EXTERN int $2_it;";
  651:                                         $def .=
  652:                                             "#INFO:"
  653:                                                 .join(',',@current_platforms).":"
  654:                                                     .join(',',@current_algorithms).";";
  655:                                         # Variant for platforms that have to
  656:                                         # access globale variables in shared
  657:                                         # libraries through functions
  658:                                         &$make_variant("$2_it","$2_it",
  659:                                                       "EXPORT_VAR_AS_FUNCTION",
  660:                                                       "FUNCTION");
  661:                                         next;
  662:                                 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS\s*\(\s*(\w*)\s*\)/ ||
  663:                                          /^\s*DECLARE_ASN1_FUNCTIONS_const\s*\(\s*(\w*)\s*\)/) {
  664:                                         $def .= "int d2i_$1(void);";
  665:                                         $def .= "int i2d_$1(void);";
  666:                                         $def .= "int $1_free(void);";
  667:                                         $def .= "int $1_new(void);";
  668:                                         # Variant for platforms that do not
  669:                                         # have to access globale variables
  670:                                         # in shared libraries through functions
  671:                                         $def .=
  672:                                             "#INFO:"
  673:                                                 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
  674:                                                     .join(',',@current_algorithms).";";
  675:                                         $def .= "OPENSSL_EXTERN int $1_it;";
  676:                                         $def .=
  677:                                             "#INFO:"
  678:                                                 .join(',',@current_platforms).":"
  679:                                                     .join(',',@current_algorithms).";";
  680:                                         # Variant for platforms that have to
  681:                                         # access globale variables in shared
  682:                                         # libraries through functions
  683:                                         &$make_variant("$1_it","$1_it",
  684:                                                       "EXPORT_VAR_AS_FUNCTION",
  685:                                                       "FUNCTION");
  686:                                         next;
  687:                                 } elsif (/^\s*DECLARE_ASN1_ENCODE_FUNCTIONS_const\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
  688:                                         $def .= "int d2i_$2(void);";
  689:                                         $def .= "int i2d_$2(void);";
  690:                                         # Variant for platforms that do not
  691:                                         # have to access globale variables
  692:                                         # in shared libraries through functions
  693:                                         $def .=
  694:                                             "#INFO:"
  695:                                                 .join(',',"!EXPORT_VAR_AS_FUNCTION",@current_platforms).":"
  696:                                                     .join(',',@current_algorithms).";";
  697:                                         $def .= "OPENSSL_EXTERN int $2_it;";
  698:                                         $def .=
  699:                                             "#INFO:"
  700:                                                 .join(',',@current_platforms).":"
  701:                                                     .join(',',@current_algorithms).";";
  702:                                         # Variant for platforms that have to
  703:                                         # access globale variables in shared
  704:                                         # libraries through functions
  705:                                         &$make_variant("$2_it","$2_it",
  706:                                                       "EXPORT_VAR_AS_FUNCTION",
  707:                                                       "FUNCTION");
  708:                                         next;
  709:                                 } elsif (/^\s*DECLARE_ASN1_ALLOC_FUNCTIONS\s*\(\s*(\w*)\s*\)/) {
  710:                                         $def .= "int $1_free(void);";
  711:                                         $def .= "int $1_new(void);";
  712:                                         next;
  713:                                 } elsif (/^\s*DECLARE_ASN1_FUNCTIONS_name\s*\(\s*(\w*)\s*,\s*(\w*)\s*\)/) {
  714:                                         $def .= "int d2i_$2(void);";
  715:                                         $def .= "int i2d_$2(void);";
  716:                                         $def .= "int $2_free(void);";