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