1#!/usr/local/bin/perl -w 2 3my $config = "crypto/err/openssl.ec"; 4my $debug = 0; 5my $rebuild = 0; 6my $static = 1; 7my $recurse = 0; 8my $reindex = 0; 9my $dowrite = 0; 10my $staticloader = ""; 11 12my $pack_errcode; 13my $load_errcode; 14 15while (@ARGV) { 16 my $arg = $ARGV[0]; 17 if($arg eq "-conf") { 18 shift @ARGV; 19 $config = shift @ARGV; 20 } elsif($arg eq "-debug") { 21 $debug = 1; 22 shift @ARGV; 23 } elsif($arg eq "-rebuild") { 24 $rebuild = 1; 25 shift @ARGV; 26 } elsif($arg eq "-recurse") { 27 $recurse = 1; 28 shift @ARGV; 29 } elsif($arg eq "-reindex") { 30 $reindex = 1; 31 shift @ARGV; 32 } elsif($arg eq "-nostatic") { 33 $static = 0; 34 shift @ARGV; 35 } elsif($arg eq "-staticloader") { 36 $staticloader = "static "; 37 shift @ARGV; 38 } elsif($arg eq "-write") { 39 $dowrite = 1; 40 shift @ARGV; 41 } else { 42 last; 43 } 44} 45 46if($recurse) { 47 @source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>); 48} else { 49 @source = @ARGV; 50} 51 52# Read in the config file 53 54open(IN, "<$config") || die "Can't open config file $config"; 55 56# Parse config file 57 58while(<IN>) 59{ 60 if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) { 61 $hinc{$1} = $2; 62 $libinc{$2} = $1; 63 $cskip{$3} = $1; 64 if($3 ne "NONE") { 65 $csrc{$1} = $3; 66 $fmax{$1} = 99; 67 $rmax{$1} = 99; 68 $fassigned{$1} = ":"; 69 $rassigned{$1} = ":"; 70 $fnew{$1} = 0; 71 $rnew{$1} = 0; 72 } 73 } elsif (/^F\s+(\S+)/) { 74 # Add extra function with $1 75 } elsif (/^R\s+(\S+)\s+(\S+)/) { 76 $rextra{$1} = $2; 77 $rcodes{$1} = $2; 78 } 79} 80 81close IN; 82 83# Scan each header file in turn and make a list of error codes 84# and function names 85 86while (($hdr, $lib) = each %libinc) 87{ 88 next if($hdr eq "NONE"); 89 print STDERR "Scanning header file $hdr\n" if $debug; 90 my $line = "", $def= "", $linenr = 0, $gotfile = 0; 91 if (open(IN, "<$hdr")) { 92 $gotfile = 1; 93 while(<IN>) { 94 $linenr++; 95 print STDERR "line: $linenr\r" if $debug; 96 97 last if(/BEGIN\s+ERROR\s+CODES/); 98 if ($line ne '') { 99 $_ = $line . $_; 100 $line = ''; 101 } 102 103 if (/\\$/) { 104 $line = $_; 105 next; 106 } 107 108 if(/\/\*/) { 109 if (not /\*\//) { # multiline comment... 110 $line = $_; # ... just accumulate 111 next; 112 } else { 113 s/\/\*.*?\*\///gs; # wipe it 114 } 115 } 116 117 if ($cpp) { 118 $cpp++ if /^#\s*if/; 119 $cpp-- if /^#\s*endif/; 120 next; 121 } 122 $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration 123 124 next if (/^\#/); # skip preprocessor directives 125 126 s/{[^{}]*}//gs; # ignore {} blocks 127 128 if (/\{|\/\*/) { # Add a } so editor works... 129 $line = $_; 130 } else { 131 $def .= $_; 132 } 133 } 134 } 135 136 print STDERR " \r" if $debug; 137 $defnr = 0; 138 # Delete any DECLARE_ macros 139 $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs; 140 foreach (split /;/, $def) { 141 $defnr++; 142 print STDERR "def: $defnr\r" if $debug; 143 144 # The goal is to collect function names from function declarations. 145 146 s/^[\n\s]*//g; 147 s/[\n\s]*$//g; 148 149 # Skip over recognized non-function declarations 150 next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/); 151 152 # Remove STACK_OF(foo) 153 s/STACK_OF\(\w+\)/void/; 154 155 # Reduce argument lists to empty () 156 # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {} 157 while(/\(.*\)/s) { 158 s/\([^\(\)]+\)/\{\}/gs; 159 s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f 160 } 161 # pretend as we didn't use curly braces: {} -> () 162 s/\{\}/\(\)/gs; 163 164 if (/(\w+)\s*\(\).*/s) { # first token prior [first] () is 165 my $name = $1; # a function name! 166 $name =~ tr/[a-z]/[A-Z]/; 167 $ftrans{$name} = $1; 168 } elsif (/[\(\)]/ and not (/=/)) { 169 print STDERR "Header $hdr: cannot parse: $_;\n"; 170 } 171 } 172 173 print STDERR " \r" if $debug; 174 175 next if $reindex; 176 177 # Scan function and reason codes and store them: keep a note of the 178 # maximum code used. 179 180 if ($gotfile) { 181 while(<IN>) { 182 if(/^\#define\s+(\S+)\s+(\S+)/) { 183 $name = $1; 184 $code = $2; 185 next if $name =~ /^${lib}err/; 186 unless($name =~ /^${lib}_([RF])_(\w+)$/) { 187 print STDERR "Invalid error code $name\n"; 188 next; 189 } 190 if($1 eq "R") { 191 $rcodes{$name} = $code; 192 if ($rassigned{$lib} =~ /:$code:/) { 193 print STDERR "!! ERROR: $lib reason code $code assigned twice\n"; 194 } 195 $rassigned{$lib} .= "$code:"; 196 if(!(exists $rextra{$name}) && 197 ($code > $rmax{$lib}) ) { 198 $rmax{$lib} = $code; 199 } 200 } else { 201 if ($fassigned{$lib} =~ /:$code:/) { 202 print STDERR "!! ERROR: $lib function code $code assigned twice\n"; 203 } 204 $fassigned{$lib} .= "$code:"; 205 if($code > $fmax{$lib}) { 206 $fmax{$lib} = $code; 207 } 208 $fcodes{$name} = $code; 209 } 210 } 211 } 212 } 213 214 if ($debug) { 215 if (defined($fmax{$lib})) { 216 print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n"; 217 $fassigned{$lib} =~ m/^:(.*):$/; 218 @fassigned = sort {$a <=> $b} split(":", $1); 219 print STDERR " @fassigned\n"; 220 } 221 if (defined($rmax{$lib})) { 222 print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n"; 223 $rassigned{$lib} =~ m/^:(.*):$/; 224 @rassigned = sort {$a <=> $b} split(":", $1); 225 print STDERR " @rassigned\n"; 226 } 227 } 228 229 if ($lib eq "SSL") { 230 if ($rmax{$lib} >= 1000) { 231 print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n"; 232 print STDERR "!! Any new alerts must be added to $config.\n"; 233 print STDERR "\n"; 234 } 235 } 236 close IN; 237} 238 239# Scan each C source file and look for function and reason codes 240# This is done by looking for strings that "look like" function or 241# reason codes: basically anything consisting of all upper case and 242# numerics which has _F_ or _R_ in it and which has the name of an 243# error library at the start. This seems to work fine except for the 244# oddly named structure BIO_F_CTX which needs to be ignored. 245# If a code doesn't exist in list compiled from headers then mark it 246# with the value "X" as a place holder to give it a value later. 247# Store all function and reason codes found in %ufcodes and %urcodes 248# so all those unreferenced can be printed out. 249 250 251foreach $file (@source) { 252 # Don't parse the error source file. 253 next if exists $cskip{$file}; 254 print STDERR "File loaded: ".$file."\r" if $debug; 255 open(IN, "<$file") || die "Can't open source file $file\n"; 256 while(<IN>) { 257 if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) { 258 next unless exists $csrc{$2}; 259 next if($1 eq "BIO_F_BUFFER_CTX"); 260 $ufcodes{$1} = 1; 261 if(!exists $fcodes{$1}) { 262 $fcodes{$1} = "X"; 263 $fnew{$2}++; 264 } 265 $notrans{$1} = 1 unless exists $ftrans{$3}; 266 } 267 if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) { 268 next unless exists $csrc{$2}; 269 $urcodes{$1} = 1; 270 if(!exists $rcodes{$1}) { 271 $rcodes{$1} = "X"; 272 $rnew{$2}++; 273 } 274 } 275 } 276 close IN; 277} 278print STDERR " \n" if $debug; 279 280# Now process each library in turn. 281 282foreach $lib (keys %csrc) 283{ 284 my $hfile = $hinc{$lib}; 285 my $cfile = $csrc{$lib}; 286 if(!$fnew{$lib} && !$rnew{$lib}) { 287 print STDERR "$lib:\t\tNo new error codes\n"; 288 next unless $rebuild; 289 } else { 290 print STDERR "$lib:\t\t$fnew{$lib} New Functions,"; 291 print STDERR " $rnew{$lib} New Reasons.\n"; 292 next unless $dowrite; 293 } 294 295 # If we get here then we have some new error codes so we 296 # need to rebuild the header file and C file. 297 298 # Make a sorted list of error and reason codes for later use. 299 300 my @function = sort grep(/^${lib}_/,keys %fcodes); 301 my @reasons = sort grep(/^${lib}_/,keys %rcodes); 302 303 # Rewrite the header file 304 305 if (open(IN, "<$hfile")) { 306 # Copy across the old file 307 while(<IN>) { 308 push @out, $_; 309 last if (/BEGIN ERROR CODES/); 310 } 311 close IN; 312 } else { 313 push @out, 314"/* ====================================================================\n", 315" * Copyright (c) 2001-2005 The OpenSSL Project. All rights reserved.\n", 316" *\n", 317" * Redistribution and use in source and binary forms, with or without\n", 318" * modification, are permitted provided that the following conditions\n", 319" * are met:\n", 320" *\n", 321" * 1. Redistributions of source code must retain the above copyright\n", 322" * notice, this list of conditions and the following disclaimer. \n", 323" *\n", 324" * 2. Redistributions in binary form must reproduce the above copyright\n", 325" * notice, this list of conditions and the following disclaimer in\n", 326" * the documentation and/or other materials provided with the\n", 327" * distribution.\n", 328" *\n", 329" * 3. All advertising materials mentioning features or use of this\n", 330" * software must display the following acknowledgment:\n", 331" * \"This product includes software developed by the OpenSSL Project\n", 332" * for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n", 333" *\n", 334" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n", 335" * endorse or promote products derived from this software without\n", 336" * prior written permission. For written permission, please contact\n", 337" * openssl-core\@openssl.org.\n", 338" *\n", 339" * 5. Products derived from this software may not be called \"OpenSSL\"\n", 340" * nor may \"OpenSSL\" appear in their names without prior written\n", 341" * permission of the OpenSSL Project.\n", 342" *\n", 343" * 6. Redistributions of any form whatsoever must retain the following\n", 344" * acknowledgment:\n", 345" * \"This product includes software developed by the OpenSSL Project\n", 346" * for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n", 347" *\n", 348" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n", 349" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n", 350" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n", 351" * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\n", 352" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n", 353" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n", 354" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n", 355" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n", 356" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n", 357" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n", 358" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n", 359" * OF THE POSSIBILITY OF SUCH DAMAGE.\n", 360" * ====================================================================\n", 361" *\n", 362" * This product includes cryptographic software written by Eric Young\n", 363" * (eay\@cryptsoft.com). This product includes software written by Tim\n", 364" * Hudson (tjh\@cryptsoft.com).\n", 365" *\n", 366" */\n", 367"\n", 368"#ifndef HEADER_${lib}_ERR_H\n", 369"#define HEADER_${lib}_ERR_H\n", 370"\n", 371"/* BEGIN ERROR CODES */\n"; 372 } 373 open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n"; 374 375 print OUT @out; 376 undef @out; 377 print OUT <<"EOF"; 378/* The following lines are auto generated by the script mkerr.pl. Any changes 379 * made after this point may be overwritten when the script is next run. 380 */ 381EOF 382 if($static) { 383 print OUT <<"EOF"; 384${staticloader}void ERR_load_${lib}_strings(void); 385 386EOF 387 } else { 388 print OUT <<"EOF"; 389${staticloader}void ERR_load_${lib}_strings(void); 390${staticloader}void ERR_unload_${lib}_strings(void); 391${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line); 392#define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__) 393 394EOF 395 } 396 print OUT <<"EOF"; 397/* Error codes for the $lib functions. */ 398 399/* Function codes. */ 400EOF 401 402 foreach $i (@function) { 403 $z=6-int(length($i)/8); 404 if($fcodes{$i} eq "X") { 405 $fassigned{$lib} =~ m/^:([^:]*):/; 406 $findcode = $1; 407 if (!defined($findcode)) { 408 $findcode = $fmax{$lib}; 409 } 410 while ($fassigned{$lib} =~ m/:$findcode:/) { 411 $findcode++; 412 } 413 $fcodes{$i} = $findcode; 414 $fassigned{$lib} .= "$findcode:"; 415 print STDERR "New Function code $i\n" if $debug; 416 } 417 printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z; 418 } 419 420 print OUT "\n/* Reason codes. */\n"; 421 422 foreach $i (@reasons) { 423 $z=6-int(length($i)/8); 424 if($rcodes{$i} eq "X") { 425 $rassigned{$lib} =~ m/^:([^:]*):/; 426 $findcode = $1; 427 if (!defined($findcode)) { 428 $findcode = $rmax{$lib}; 429 } 430 while ($rassigned{$lib} =~ m/:$findcode:/) { 431 $findcode++; 432 } 433 $rcodes{$i} = $findcode; 434 $rassigned{$lib} .= "$findcode:"; 435 print STDERR "New Reason code $i\n" if $debug; 436 } 437 printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z; 438 } 439 print OUT <<"EOF"; 440 441#ifdef __cplusplus 442} 443#endif 444#endif 445EOF 446 close OUT; 447 448 # Rewrite the C source file containing the error details. 449 450 # First, read any existing reason string definitions: 451 my %err_reason_strings; 452 if (open(IN,"<$cfile")) { 453 while (<IN>) { 454 if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) { 455 $err_reason_strings{$1} = $2; 456 } 457 } 458 close(IN); 459 } 460 461 my $hincf; 462 if($static) { 463 $hfile =~ /([^\/]+)$/; 464 $hincf = "<openssl/$1>"; 465 } else { 466 $hincf = "\"$hfile\""; 467 } 468 469 # If static we know the error code at compile time so use it 470 # in error definitions. 471 472 if ($static) 473 { 474 $pack_errcode = "ERR_LIB_${lib}"; 475 $load_errcode = "0"; 476 } 477 else 478 { 479 $pack_errcode = "0"; 480 $load_errcode = "ERR_LIB_${lib}"; 481 } 482 483 484 open (OUT,">$cfile") || die "Can't open $cfile for writing"; 485 486 print OUT <<"EOF"; 487/* $cfile */ 488/* ==================================================================== 489 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 490 * 491 * Redistribution and use in source and binary forms, with or without 492 * modification, are permitted provided that the following conditions 493 * are met: 494 * 495 * 1. Redistributions of source code must retain the above copyright 496 * notice, this list of conditions and the following disclaimer. 497 * 498 * 2. Redistributions in binary form must reproduce the above copyright 499 * notice, this list of conditions and the following disclaimer in 500 * the documentation and/or other materials provided with the 501 * distribution. 502 * 503 * 3. All advertising materials mentioning features or use of this 504 * software must display the following acknowledgment: 505 * "This product includes software developed by the OpenSSL Project 506 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 507 * 508 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 509 * endorse or promote products derived from this software without 510 * prior written permission. For written permission, please contact 511 * openssl-core\@OpenSSL.org. 512 * 513 * 5. Products derived from this software may not be called "OpenSSL" 514 * nor may "OpenSSL" appear in their names without prior written 515 * permission of the OpenSSL Project. 516 * 517 * 6. Redistributions of any form whatsoever must retain the following 518 * acknowledgment: 519 * "This product includes software developed by the OpenSSL Project 520 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 521 * 522 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 523 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 524 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 525 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 526 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 527 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 528 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 529 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 530 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 531 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 532 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 533 * OF THE POSSIBILITY OF SUCH DAMAGE. 534 * ==================================================================== 535 * 536 * This product includes cryptographic software written by Eric Young 537 * (eay\@cryptsoft.com). This product includes software written by Tim 538 * Hudson (tjh\@cryptsoft.com). 539 * 540 */ 541 542/* NOTE: this file was auto generated by the mkerr.pl script: any changes 543 * made to it will be overwritten when the script next updates this file, 544 * only reason strings will be preserved. 545 */ 546 547#include <stdio.h> 548#include <openssl/err.h> 549#include $hincf 550 551/* BEGIN ERROR CODES */ 552#ifndef OPENSSL_NO_ERR 553 554#define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0) 555#define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason) 556 557static ERR_STRING_DATA ${lib}_str_functs[]= 558 { 559EOF 560 # Add each function code: if a function name is found then use it. 561 foreach $i (@function) { 562 my $fn; 563 $i =~ /^${lib}_F_(\S+)$/; 564 $fn = $1; 565 if(exists $ftrans{$fn}) { 566 $fn = $ftrans{$fn}; 567 } 568# print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n"; 569 print OUT "{ERR_FUNC($i),\t\"$fn\"},\n"; 570 } 571 print OUT <<"EOF"; 572{0,NULL} 573 }; 574 575static ERR_STRING_DATA ${lib}_str_reasons[]= 576 { 577EOF 578 # Add each reason code. 579 foreach $i (@reasons) { 580 my $rn; 581 my $rstr = "ERR_REASON($i)"; 582 my $nspc = 0; 583 if (exists $err_reason_strings{$i}) { 584 $rn = $err_reason_strings{$i}; 585 } else { 586 $i =~ /^${lib}_R_(\S+)$/; 587 $rn = $1; 588 $rn =~ tr/_[A-Z]/ [a-z]/; 589 } 590 $nspc = 40 - length($rstr) unless length($rstr) > 40; 591 $nspc = " " x $nspc; 592 print OUT "{${rstr}${nspc},\"$rn\"},\n"; 593 } 594if($static) { 595 print OUT <<"EOF"; 596{0,NULL} 597 }; 598 599#endif 600 601${staticloader}void ERR_load_${lib}_strings(void) 602 { 603#ifndef OPENSSL_NO_ERR 604 605 if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) 606 { 607 ERR_load_strings($load_errcode,${lib}_str_functs); 608 ERR_load_strings($load_errcode,${lib}_str_reasons); 609 } 610#endif 611 } 612EOF 613} else { 614 print OUT <<"EOF"; 615{0,NULL} 616 }; 617 618#endif 619 620#ifdef ${lib}_LIB_NAME 621static ERR_STRING_DATA ${lib}_lib_name[]= 622 { 623{0 ,${lib}_LIB_NAME}, 624{0,NULL} 625 }; 626#endif 627 628 629static int ${lib}_lib_error_code=0; 630static int ${lib}_error_init=1; 631 632${staticloader}void ERR_load_${lib}_strings(void) 633 { 634 if (${lib}_lib_error_code == 0) 635 ${lib}_lib_error_code=ERR_get_next_error_library(); 636 637 if (${lib}_error_init) 638 { 639 ${lib}_error_init=0; 640#ifndef OPENSSL_NO_ERR 641 ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs); 642 ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons); 643#endif 644 645#ifdef ${lib}_LIB_NAME 646 ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0); 647 ERR_load_strings(0,${lib}_lib_name); 648#endif 649 } 650 } 651 652${staticloader}void ERR_unload_${lib}_strings(void) 653 { 654 if (${lib}_error_init == 0) 655 { 656#ifndef OPENSSL_NO_ERR 657 ERR_unload_strings(${lib}_lib_error_code,${lib}_str_functs); 658 ERR_unload_strings(${lib}_lib_error_code,${lib}_str_reasons); 659#endif 660 661#ifdef ${lib}_LIB_NAME 662 ERR_unload_strings(0,${lib}_lib_name); 663#endif 664 ${lib}_error_init=1; 665 } 666 } 667 668${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line) 669 { 670 if (${lib}_lib_error_code == 0) 671 ${lib}_lib_error_code=ERR_get_next_error_library(); 672 ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line); 673 } 674EOF 675 676} 677 678 close OUT; 679 undef %err_reason_strings; 680} 681 682if($debug && defined(%notrans)) { 683 print STDERR "The following function codes were not translated:\n"; 684 foreach(sort keys %notrans) 685 { 686 print STDERR "$_\n"; 687 } 688} 689 690# Make a list of unreferenced function and reason codes 691 692foreach (keys %fcodes) { 693 push (@funref, $_) unless exists $ufcodes{$_}; 694} 695 696foreach (keys %rcodes) { 697 push (@runref, $_) unless exists $urcodes{$_}; 698} 699 700if($debug && defined(@funref) ) { 701 print STDERR "The following function codes were not referenced:\n"; 702 foreach(sort @funref) 703 { 704 print STDERR "$_\n"; 705 } 706} 707 708if($debug && defined(@runref) ) { 709 print STDERR "The following reason codes were not referenced:\n"; 710 foreach(sort @runref) 711 { 712 print STDERR "$_\n"; 713 } 714} 715