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