155714Skris#!/usr/local/bin/perl -w 255714Skris 355714Skrismy $config = "crypto/err/openssl.ec"; 4238405Sjkimmy $hprefix = "openssl/"; 555714Skrismy $debug = 0; 655714Skrismy $rebuild = 0; 755714Skrismy $static = 1; 855714Skrismy $recurse = 0; 955714Skrismy $reindex = 0; 1055714Skrismy $dowrite = 0; 11109998Smarkmmy $staticloader = ""; 1255714Skris 13160814Ssimonmy $pack_errcode; 14160814Ssimonmy $load_errcode; 15160814Ssimon 16238405Sjkimmy $errcount; 17238405Sjkim 1855714Skriswhile (@ARGV) { 1955714Skris my $arg = $ARGV[0]; 2055714Skris if($arg eq "-conf") { 2155714Skris shift @ARGV; 2255714Skris $config = shift @ARGV; 23238405Sjkim } elsif($arg eq "-hprefix") { 24238405Sjkim shift @ARGV; 25238405Sjkim $hprefix = shift @ARGV; 2655714Skris } elsif($arg eq "-debug") { 2755714Skris $debug = 1; 2855714Skris shift @ARGV; 2955714Skris } elsif($arg eq "-rebuild") { 3055714Skris $rebuild = 1; 3155714Skris shift @ARGV; 3255714Skris } elsif($arg eq "-recurse") { 3355714Skris $recurse = 1; 3455714Skris shift @ARGV; 3555714Skris } elsif($arg eq "-reindex") { 3655714Skris $reindex = 1; 3755714Skris shift @ARGV; 3855714Skris } elsif($arg eq "-nostatic") { 3955714Skris $static = 0; 4055714Skris shift @ARGV; 41109998Smarkm } elsif($arg eq "-staticloader") { 42109998Smarkm $staticloader = "static "; 43109998Smarkm shift @ARGV; 4455714Skris } elsif($arg eq "-write") { 4555714Skris $dowrite = 1; 4655714Skris shift @ARGV; 47238405Sjkim } elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") { 48238405Sjkim print STDERR <<"EOF"; 49238405Sjkimmkerr.pl [options] ... 50238405Sjkim 51238405SjkimOptions: 52238405Sjkim 53238405Sjkim -conf F Use the config file F instead of the default one: 54238405Sjkim crypto/err/openssl.ec 55238405Sjkim 56238405Sjkim -hprefix P Prepend the filenames in generated #include <header> 57238405Sjkim statements with prefix P. Default: 'openssl/' (without 58238405Sjkim the quotes, naturally) 59238405Sjkim 60238405Sjkim -debug Turn on debugging verbose output on stderr. 61238405Sjkim 62238405Sjkim -rebuild Rebuild all header and C source files, irrespective of the 63238405Sjkim fact if any error or function codes have been added/removed. 64238405Sjkim Default: only update files for libraries which saw change 65238405Sjkim (of course, this requires '-write' as well, or no 66238405Sjkim files will be touched!) 67238405Sjkim 68238405Sjkim -recurse scan a preconfigured set of directories / files for error and 69238405Sjkim function codes: 70238405Sjkim (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>) 71238405Sjkim When this option is NOT specified, the filelist is taken from 72238405Sjkim the commandline instead. Here, wildcards may be embedded. (Be 73238405Sjkim sure to escape those to prevent the shell from expanding them 74238405Sjkim for you when you wish mkerr.pl to do so instead.) 75238405Sjkim Default: take file list to scan from the command line. 76238405Sjkim 77238405Sjkim -reindex Discard the numeric values previously assigned to the error 78238405Sjkim and function codes as extracted from the scanned header files; 79238405Sjkim instead renumber all of them starting from 100. (Note that 80238405Sjkim the numbers assigned through 'R' records in the config file 81238405Sjkim remain intact.) 82238405Sjkim Default: keep previously assigned numbers. (You are warned 83238405Sjkim when collisions are detected.) 84238405Sjkim 85238405Sjkim -nostatic Generates a different source code, where these additional 86238405Sjkim functions are generated for each library specified in the 87238405Sjkim config file: 88238405Sjkim void ERR_load_<LIB>_strings(void); 89238405Sjkim void ERR_unload_<LIB>_strings(void); 90238405Sjkim void ERR_<LIB>_error(int f, int r, char *fn, int ln); 91238405Sjkim #define <LIB>err(f,r) ERR_<LIB>_error(f,r,__FILE__,__LINE__) 92238405Sjkim while the code facilitates the use of these in an environment 93238405Sjkim where the error support routines are dynamically loaded at 94238405Sjkim runtime. 95238405Sjkim Default: 'static' code generation. 96238405Sjkim 97238405Sjkim -staticloader Prefix generated functions with the 'static' scope modifier. 98238405Sjkim Default: don't write any scope modifier prefix. 99238405Sjkim 100238405Sjkim -write Actually (over)write the generated code to the header and C 101238405Sjkim source files as assigned to each library through the config 102238405Sjkim file. 103238405Sjkim Default: don't write. 104238405Sjkim 105238405Sjkim -help / -h / -? / --help Show this help text. 106238405Sjkim 107238405Sjkim ... Additional arguments are added to the file list to scan, 108238405Sjkim assuming '-recurse' was NOT specified on the command line. 109238405Sjkim 110238405SjkimEOF 111238405Sjkim exit 1; 11255714Skris } else { 11355714Skris last; 11455714Skris } 11555714Skris} 11655714Skris 11755714Skrisif($recurse) { 118238405Sjkim @source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>); 11955714Skris} else { 12055714Skris @source = @ARGV; 12155714Skris} 12255714Skris 12355714Skris# Read in the config file 12455714Skris 12555714Skrisopen(IN, "<$config") || die "Can't open config file $config"; 12655714Skris 12755714Skris# Parse config file 12855714Skris 12955714Skriswhile(<IN>) 13055714Skris{ 13155714Skris if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) { 13255714Skris $hinc{$1} = $2; 13389837Skris $libinc{$2} = $1; 13455714Skris $cskip{$3} = $1; 13555714Skris if($3 ne "NONE") { 13655714Skris $csrc{$1} = $3; 137238405Sjkim $fmax{$1} = 100; 138238405Sjkim $rmax{$1} = 100; 139160814Ssimon $fassigned{$1} = ":"; 140160814Ssimon $rassigned{$1} = ":"; 14155714Skris $fnew{$1} = 0; 14255714Skris $rnew{$1} = 0; 14355714Skris } 14455714Skris } elsif (/^F\s+(\S+)/) { 14555714Skris # Add extra function with $1 14655714Skris } elsif (/^R\s+(\S+)\s+(\S+)/) { 14755714Skris $rextra{$1} = $2; 14855714Skris $rcodes{$1} = $2; 14955714Skris } 15055714Skris} 15155714Skris 15255714Skrisclose IN; 15355714Skris 15455714Skris# Scan each header file in turn and make a list of error codes 15555714Skris# and function names 15655714Skris 15789837Skriswhile (($hdr, $lib) = each %libinc) 15855714Skris{ 15955714Skris next if($hdr eq "NONE"); 16055714Skris print STDERR "Scanning header file $hdr\n" if $debug; 161109998Smarkm my $line = "", $def= "", $linenr = 0, $gotfile = 0; 162109998Smarkm if (open(IN, "<$hdr")) { 163109998Smarkm $gotfile = 1; 164109998Smarkm while(<IN>) { 165109998Smarkm $linenr++; 166109998Smarkm print STDERR "line: $linenr\r" if $debug; 16768651Skris 168109998Smarkm last if(/BEGIN\s+ERROR\s+CODES/); 169109998Smarkm if ($line ne '') { 170109998Smarkm $_ = $line . $_; 171109998Smarkm $line = ''; 172109998Smarkm } 17355714Skris 174109998Smarkm if (/\\$/) { 175109998Smarkm $line = $_; 176109998Smarkm next; 177109998Smarkm } 17855714Skris 179160814Ssimon if(/\/\*/) { 180160814Ssimon if (not /\*\//) { # multiline comment... 181160814Ssimon $line = $_; # ... just accumulate 182160814Ssimon next; 183160814Ssimon } else { 184160814Ssimon s/\/\*.*?\*\///gs; # wipe it 185160814Ssimon } 186160814Ssimon } 187160814Ssimon 188109998Smarkm if ($cpp) { 189160814Ssimon $cpp++ if /^#\s*if/; 190160814Ssimon $cpp-- if /^#\s*endif/; 191109998Smarkm next; 192109998Smarkm } 193160814Ssimon $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration 19455714Skris 195109998Smarkm next if (/^\#/); # skip preprocessor directives 19655714Skris 197109998Smarkm s/{[^{}]*}//gs; # ignore {} blocks 19855714Skris 199109998Smarkm if (/\{|\/\*/) { # Add a } so editor works... 200109998Smarkm $line = $_; 201109998Smarkm } else { 202109998Smarkm $def .= $_; 203109998Smarkm } 20455714Skris } 20555714Skris } 20655714Skris 20768651Skris print STDERR " \r" if $debug; 20868651Skris $defnr = 0; 209167612Ssimon # Delete any DECLARE_ macros 210167612Ssimon $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs; 21155714Skris foreach (split /;/, $def) { 21268651Skris $defnr++; 21368651Skris print STDERR "def: $defnr\r" if $debug; 21468651Skris 215160814Ssimon # The goal is to collect function names from function declarations. 216160814Ssimon 21755714Skris s/^[\n\s]*//g; 21855714Skris s/[\n\s]*$//g; 219160814Ssimon 220160814Ssimon # Skip over recognized non-function declarations 221160814Ssimon next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/); 222160814Ssimon 223167612Ssimon # Remove STACK_OF(foo) 224167612Ssimon s/STACK_OF\(\w+\)/void/; 225167612Ssimon 226160814Ssimon # Reduce argument lists to empty () 227160814Ssimon # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {} 228160814Ssimon while(/\(.*\)/s) { 229160814Ssimon s/\([^\(\)]+\)/\{\}/gs; 230160814Ssimon s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f 231160814Ssimon } 232160814Ssimon # pretend as we didn't use curly braces: {} -> () 233160814Ssimon s/\{\}/\(\)/gs; 234160814Ssimon 235160814Ssimon if (/(\w+)\s*\(\).*/s) { # first token prior [first] () is 236160814Ssimon my $name = $1; # a function name! 23755714Skris $name =~ tr/[a-z]/[A-Z]/; 23855714Skris $ftrans{$name} = $1; 239160814Ssimon } elsif (/[\(\)]/ and not (/=/)) { 24055714Skris print STDERR "Header $hdr: cannot parse: $_;\n"; 24155714Skris } 24255714Skris } 24355714Skris 24468651Skris print STDERR " \r" if $debug; 24568651Skris 24655714Skris next if $reindex; 24755714Skris 24855714Skris # Scan function and reason codes and store them: keep a note of the 24955714Skris # maximum code used. 25055714Skris 251109998Smarkm if ($gotfile) { 252160814Ssimon while(<IN>) { 253280304Sjkim if(/^\#\s*define\s+(\S+)\s+(\S+)/) { 25455714Skris $name = $1; 25555714Skris $code = $2; 256109998Smarkm next if $name =~ /^${lib}err/; 25755714Skris unless($name =~ /^${lib}_([RF])_(\w+)$/) { 25855714Skris print STDERR "Invalid error code $name\n"; 25955714Skris next; 26055714Skris } 26155714Skris if($1 eq "R") { 26255714Skris $rcodes{$name} = $code; 263160814Ssimon if ($rassigned{$lib} =~ /:$code:/) { 264238405Sjkim print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n"; 265238405Sjkim ++$errcount; 266160814Ssimon } 267160814Ssimon $rassigned{$lib} .= "$code:"; 26855714Skris if(!(exists $rextra{$name}) && 26955714Skris ($code > $rmax{$lib}) ) { 27055714Skris $rmax{$lib} = $code; 27155714Skris } 27255714Skris } else { 273160814Ssimon if ($fassigned{$lib} =~ /:$code:/) { 274238405Sjkim print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n"; 275238405Sjkim ++$errcount; 276160814Ssimon } 277160814Ssimon $fassigned{$lib} .= "$code:"; 27855714Skris if($code > $fmax{$lib}) { 27955714Skris $fmax{$lib} = $code; 28055714Skris } 28155714Skris $fcodes{$name} = $code; 28255714Skris } 28355714Skris } 284160814Ssimon } 28555714Skris } 286160814Ssimon 287160814Ssimon if ($debug) { 288160814Ssimon if (defined($fmax{$lib})) { 289160814Ssimon print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n"; 290160814Ssimon $fassigned{$lib} =~ m/^:(.*):$/; 291160814Ssimon @fassigned = sort {$a <=> $b} split(":", $1); 292160814Ssimon print STDERR " @fassigned\n"; 293160814Ssimon } 294160814Ssimon if (defined($rmax{$lib})) { 295160814Ssimon print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n"; 296160814Ssimon $rassigned{$lib} =~ m/^:(.*):$/; 297160814Ssimon @rassigned = sort {$a <=> $b} split(":", $1); 298160814Ssimon print STDERR " @rassigned\n"; 299160814Ssimon } 300160814Ssimon } 301160814Ssimon 302160814Ssimon if ($lib eq "SSL") { 303160814Ssimon if ($rmax{$lib} >= 1000) { 304160814Ssimon print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n"; 305160814Ssimon print STDERR "!! Any new alerts must be added to $config.\n"; 306238405Sjkim ++$errcount; 307160814Ssimon print STDERR "\n"; 308160814Ssimon } 309160814Ssimon } 31055714Skris close IN; 31155714Skris} 31255714Skris 31355714Skris# Scan each C source file and look for function and reason codes 31455714Skris# This is done by looking for strings that "look like" function or 31555714Skris# reason codes: basically anything consisting of all upper case and 31655714Skris# numerics which has _F_ or _R_ in it and which has the name of an 31755714Skris# error library at the start. This seems to work fine except for the 31855714Skris# oddly named structure BIO_F_CTX which needs to be ignored. 31955714Skris# If a code doesn't exist in list compiled from headers then mark it 32055714Skris# with the value "X" as a place holder to give it a value later. 32155714Skris# Store all function and reason codes found in %ufcodes and %urcodes 32255714Skris# so all those unreferenced can be printed out. 32355714Skris 32455714Skris 32555714Skrisforeach $file (@source) { 32655714Skris # Don't parse the error source file. 32755714Skris next if exists $cskip{$file}; 328160814Ssimon print STDERR "File loaded: ".$file."\r" if $debug; 32955714Skris open(IN, "<$file") || die "Can't open source file $file\n"; 33055714Skris while(<IN>) { 331238405Sjkim # skip obsoleted source files entirely! 332238405Sjkim last if(/^#error\s+obsolete/); 333238405Sjkim 33455714Skris if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) { 33555714Skris next unless exists $csrc{$2}; 33655714Skris next if($1 eq "BIO_F_BUFFER_CTX"); 33755714Skris $ufcodes{$1} = 1; 33855714Skris if(!exists $fcodes{$1}) { 33955714Skris $fcodes{$1} = "X"; 34055714Skris $fnew{$2}++; 34155714Skris } 34255714Skris $notrans{$1} = 1 unless exists $ftrans{$3}; 343238405Sjkim print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug; 34455714Skris } 34555714Skris if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) { 34655714Skris next unless exists $csrc{$2}; 34755714Skris $urcodes{$1} = 1; 34855714Skris if(!exists $rcodes{$1}) { 34955714Skris $rcodes{$1} = "X"; 35055714Skris $rnew{$2}++; 35155714Skris } 352238405Sjkim print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug; 35355714Skris } 35455714Skris } 35555714Skris close IN; 35655714Skris} 357160814Ssimonprint STDERR " \n" if $debug; 35855714Skris 35955714Skris# Now process each library in turn. 36055714Skris 36155714Skrisforeach $lib (keys %csrc) 36255714Skris{ 36355714Skris my $hfile = $hinc{$lib}; 36455714Skris my $cfile = $csrc{$lib}; 36555714Skris if(!$fnew{$lib} && !$rnew{$lib}) { 36655714Skris print STDERR "$lib:\t\tNo new error codes\n"; 36755714Skris next unless $rebuild; 36855714Skris } else { 36955714Skris print STDERR "$lib:\t\t$fnew{$lib} New Functions,"; 37055714Skris print STDERR " $rnew{$lib} New Reasons.\n"; 37155714Skris next unless $dowrite; 37255714Skris } 37355714Skris 37455714Skris # If we get here then we have some new error codes so we 37555714Skris # need to rebuild the header file and C file. 37655714Skris 37755714Skris # Make a sorted list of error and reason codes for later use. 37855714Skris 37955714Skris my @function = sort grep(/^${lib}_/,keys %fcodes); 38055714Skris my @reasons = sort grep(/^${lib}_/,keys %rcodes); 38155714Skris 38255714Skris # Rewrite the header file 38355714Skris 384109998Smarkm if (open(IN, "<$hfile")) { 385109998Smarkm # Copy across the old file 386109998Smarkm while(<IN>) { 38755714Skris push @out, $_; 38855714Skris last if (/BEGIN ERROR CODES/); 389109998Smarkm } 390109998Smarkm close IN; 391109998Smarkm } else { 392109998Smarkm push @out, 393109998Smarkm"/* ====================================================================\n", 394237657Sjkim" * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.\n", 395109998Smarkm" *\n", 396109998Smarkm" * Redistribution and use in source and binary forms, with or without\n", 397109998Smarkm" * modification, are permitted provided that the following conditions\n", 398109998Smarkm" * are met:\n", 399109998Smarkm" *\n", 400109998Smarkm" * 1. Redistributions of source code must retain the above copyright\n", 401109998Smarkm" * notice, this list of conditions and the following disclaimer. \n", 402109998Smarkm" *\n", 403109998Smarkm" * 2. Redistributions in binary form must reproduce the above copyright\n", 404109998Smarkm" * notice, this list of conditions and the following disclaimer in\n", 405109998Smarkm" * the documentation and/or other materials provided with the\n", 406109998Smarkm" * distribution.\n", 407109998Smarkm" *\n", 408109998Smarkm" * 3. All advertising materials mentioning features or use of this\n", 409109998Smarkm" * software must display the following acknowledgment:\n", 410109998Smarkm" * \"This product includes software developed by the OpenSSL Project\n", 411109998Smarkm" * for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n", 412109998Smarkm" *\n", 413109998Smarkm" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n", 414109998Smarkm" * endorse or promote products derived from this software without\n", 415109998Smarkm" * prior written permission. For written permission, please contact\n", 416109998Smarkm" * openssl-core\@openssl.org.\n", 417109998Smarkm" *\n", 418109998Smarkm" * 5. Products derived from this software may not be called \"OpenSSL\"\n", 419109998Smarkm" * nor may \"OpenSSL\" appear in their names without prior written\n", 420109998Smarkm" * permission of the OpenSSL Project.\n", 421109998Smarkm" *\n", 422109998Smarkm" * 6. Redistributions of any form whatsoever must retain the following\n", 423109998Smarkm" * acknowledgment:\n", 424109998Smarkm" * \"This product includes software developed by the OpenSSL Project\n", 425109998Smarkm" * for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n", 426109998Smarkm" *\n", 427109998Smarkm" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n", 428109998Smarkm" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n", 429109998Smarkm" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n", 430109998Smarkm" * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\n", 431109998Smarkm" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n", 432109998Smarkm" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n", 433109998Smarkm" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n", 434109998Smarkm" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n", 435109998Smarkm" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n", 436109998Smarkm" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n", 437109998Smarkm" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n", 438109998Smarkm" * OF THE POSSIBILITY OF SUCH DAMAGE.\n", 439109998Smarkm" * ====================================================================\n", 440109998Smarkm" *\n", 441109998Smarkm" * This product includes cryptographic software written by Eric Young\n", 442109998Smarkm" * (eay\@cryptsoft.com). This product includes software written by Tim\n", 443109998Smarkm" * Hudson (tjh\@cryptsoft.com).\n", 444109998Smarkm" *\n", 445109998Smarkm" */\n", 446109998Smarkm"\n", 447109998Smarkm"#ifndef HEADER_${lib}_ERR_H\n", 448109998Smarkm"#define HEADER_${lib}_ERR_H\n", 449109998Smarkm"\n", 450238405Sjkim"#ifdef __cplusplus\n", 451238405Sjkim"extern \"C\" {\n", 452238405Sjkim"#endif\n", 453238405Sjkim"\n", 454109998Smarkm"/* BEGIN ERROR CODES */\n"; 45555714Skris } 45655714Skris open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n"; 45755714Skris 45855714Skris print OUT @out; 45955714Skris undef @out; 46055714Skris print OUT <<"EOF"; 461280304Sjkim/* 462280304Sjkim * The following lines are auto generated by the script mkerr.pl. Any changes 46355714Skris * made after this point may be overwritten when the script is next run. 46455714Skris */ 465109998SmarkmEOF 466109998Smarkm if($static) { 467109998Smarkm print OUT <<"EOF"; 468109998Smarkm${staticloader}void ERR_load_${lib}_strings(void); 46955714Skris 470109998SmarkmEOF 471109998Smarkm } else { 472109998Smarkm print OUT <<"EOF"; 473109998Smarkm${staticloader}void ERR_load_${lib}_strings(void); 474109998Smarkm${staticloader}void ERR_unload_${lib}_strings(void); 475109998Smarkm${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line); 476280304Sjkim# define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__) 477109998Smarkm 478109998SmarkmEOF 479109998Smarkm } 480109998Smarkm print OUT <<"EOF"; 48155714Skris/* Error codes for the $lib functions. */ 48255714Skris 48355714Skris/* Function codes. */ 48455714SkrisEOF 48555714Skris 48655714Skris foreach $i (@function) { 487280304Sjkim $z=48 - length($i); 48855714Skris if($fcodes{$i} eq "X") { 489160814Ssimon $fassigned{$lib} =~ m/^:([^:]*):/; 490160814Ssimon $findcode = $1; 491160814Ssimon if (!defined($findcode)) { 492160814Ssimon $findcode = $fmax{$lib}; 493160814Ssimon } 494160814Ssimon while ($fassigned{$lib} =~ m/:$findcode:/) { 495160814Ssimon $findcode++; 496160814Ssimon } 497160814Ssimon $fcodes{$i} = $findcode; 498160814Ssimon $fassigned{$lib} .= "$findcode:"; 49955714Skris print STDERR "New Function code $i\n" if $debug; 50055714Skris } 501280304Sjkim printf OUT "# define $i%s $fcodes{$i}\n"," " x $z; 50255714Skris } 50355714Skris 50455714Skris print OUT "\n/* Reason codes. */\n"; 50555714Skris 50655714Skris foreach $i (@reasons) { 507280304Sjkim $z=48 - length($i); 50855714Skris if($rcodes{$i} eq "X") { 509160814Ssimon $rassigned{$lib} =~ m/^:([^:]*):/; 510160814Ssimon $findcode = $1; 511160814Ssimon if (!defined($findcode)) { 512160814Ssimon $findcode = $rmax{$lib}; 513160814Ssimon } 514160814Ssimon while ($rassigned{$lib} =~ m/:$findcode:/) { 515160814Ssimon $findcode++; 516160814Ssimon } 517160814Ssimon $rcodes{$i} = $findcode; 518160814Ssimon $rassigned{$lib} .= "$findcode:"; 51955714Skris print STDERR "New Reason code $i\n" if $debug; 52055714Skris } 521280304Sjkim printf OUT "# define $i%s $rcodes{$i}\n"," " x $z; 52255714Skris } 52355714Skris print OUT <<"EOF"; 52455714Skris 52555714Skris#ifdef __cplusplus 52655714Skris} 52755714Skris#endif 52855714Skris#endif 52955714SkrisEOF 53055714Skris close OUT; 53155714Skris 53255714Skris # Rewrite the C source file containing the error details. 53355714Skris 53459191Skris # First, read any existing reason string definitions: 53559191Skris my %err_reason_strings; 53659191Skris if (open(IN,"<$cfile")) { 537284285Sjkim my $line = ""; 53859191Skris while (<IN>) { 539284285Sjkim chomp; 540284285Sjkim $_ = $line . $_; 541284285Sjkim $line = ""; 542284285Sjkim if (/{ERR_(FUNC|REASON)\(/) { 543284285Sjkim if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) { 544284285Sjkim $err_reason_strings{$1} = $2; 545284285Sjkim } elsif (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) { 546284285Sjkim if (!exists $ftrans{$1} && ($1 ne $2)) { 547284285Sjkim print STDERR "WARNING: Mismatched function string $2\n"; 548284285Sjkim $ftrans{$1} = $2; 549284285Sjkim } 550284285Sjkim } else { 551284285Sjkim $line = $_; 552238405Sjkim } 553238405Sjkim } 55459191Skris } 55559191Skris close(IN); 55659191Skris } 55759191Skris 558238405Sjkim 55955714Skris my $hincf; 56055714Skris if($static) { 56155714Skris $hfile =~ /([^\/]+)$/; 562238405Sjkim $hincf = "<${hprefix}$1>"; 56355714Skris } else { 56455714Skris $hincf = "\"$hfile\""; 56555714Skris } 56655714Skris 567160814Ssimon # If static we know the error code at compile time so use it 568160814Ssimon # in error definitions. 56955714Skris 570160814Ssimon if ($static) 571160814Ssimon { 572160814Ssimon $pack_errcode = "ERR_LIB_${lib}"; 573160814Ssimon $load_errcode = "0"; 574160814Ssimon } 575160814Ssimon else 576160814Ssimon { 577160814Ssimon $pack_errcode = "0"; 578160814Ssimon $load_errcode = "ERR_LIB_${lib}"; 579160814Ssimon } 580160814Ssimon 581160814Ssimon 58255714Skris open (OUT,">$cfile") || die "Can't open $cfile for writing"; 58355714Skris 58455714Skris print OUT <<"EOF"; 58555714Skris/* $cfile */ 58655714Skris/* ==================================================================== 587237657Sjkim * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. 58855714Skris * 58955714Skris * Redistribution and use in source and binary forms, with or without 59055714Skris * modification, are permitted provided that the following conditions 59155714Skris * are met: 59255714Skris * 59355714Skris * 1. Redistributions of source code must retain the above copyright 594280304Sjkim * notice, this list of conditions and the following disclaimer. 59555714Skris * 59655714Skris * 2. Redistributions in binary form must reproduce the above copyright 59755714Skris * notice, this list of conditions and the following disclaimer in 59855714Skris * the documentation and/or other materials provided with the 59955714Skris * distribution. 60055714Skris * 60155714Skris * 3. All advertising materials mentioning features or use of this 60255714Skris * software must display the following acknowledgment: 60355714Skris * "This product includes software developed by the OpenSSL Project 60455714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 60555714Skris * 60655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 60755714Skris * endorse or promote products derived from this software without 60855714Skris * prior written permission. For written permission, please contact 60955714Skris * openssl-core\@OpenSSL.org. 61055714Skris * 61155714Skris * 5. Products derived from this software may not be called "OpenSSL" 61255714Skris * nor may "OpenSSL" appear in their names without prior written 61355714Skris * permission of the OpenSSL Project. 61455714Skris * 61555714Skris * 6. Redistributions of any form whatsoever must retain the following 61655714Skris * acknowledgment: 61755714Skris * "This product includes software developed by the OpenSSL Project 61855714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 61955714Skris * 62055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 62155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 62355714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 62455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 62555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 62655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 62755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 62955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 63155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 63255714Skris * ==================================================================== 63355714Skris * 63455714Skris * This product includes cryptographic software written by Eric Young 63555714Skris * (eay\@cryptsoft.com). This product includes software written by Tim 63655714Skris * Hudson (tjh\@cryptsoft.com). 63755714Skris * 63855714Skris */ 63955714Skris 640280304Sjkim/* 641280304Sjkim * NOTE: this file was auto generated by the mkerr.pl script: any changes 64259191Skris * made to it will be overwritten when the script next updates this file, 64359191Skris * only reason strings will be preserved. 64455714Skris */ 64555714Skris 64655714Skris#include <stdio.h> 64755714Skris#include <openssl/err.h> 64855714Skris#include $hincf 64955714Skris 65055714Skris/* BEGIN ERROR CODES */ 651109998Smarkm#ifndef OPENSSL_NO_ERR 652160814Ssimon 653280304Sjkim# define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0) 654280304Sjkim# define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason) 655160814Ssimon 656280304Sjkimstatic ERR_STRING_DATA ${lib}_str_functs[] = { 65755714SkrisEOF 65855714Skris # Add each function code: if a function name is found then use it. 65955714Skris foreach $i (@function) { 66055714Skris my $fn; 66155714Skris $i =~ /^${lib}_F_(\S+)$/; 66255714Skris $fn = $1; 66355714Skris if(exists $ftrans{$fn}) { 66455714Skris $fn = $ftrans{$fn}; 66555714Skris } 666160814Ssimon# print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n"; 667280304Sjkim if(length($i) + length($fn) > 58) { 668280304Sjkim print OUT " {ERR_FUNC($i),\n \"$fn\"},\n"; 669280304Sjkim } else { 670280304Sjkim print OUT " {ERR_FUNC($i), \"$fn\"},\n"; 671280304Sjkim } 67255714Skris } 67355714Skris print OUT <<"EOF"; 674280304Sjkim {0, NULL} 675280304Sjkim}; 67655714Skris 677280304Sjkimstatic ERR_STRING_DATA ${lib}_str_reasons[] = { 67855714SkrisEOF 67955714Skris # Add each reason code. 68055714Skris foreach $i (@reasons) { 68155714Skris my $rn; 682160814Ssimon my $rstr = "ERR_REASON($i)"; 68359191Skris if (exists $err_reason_strings{$i}) { 68459191Skris $rn = $err_reason_strings{$i}; 68559191Skris } else { 68659191Skris $i =~ /^${lib}_R_(\S+)$/; 68759191Skris $rn = $1; 68859191Skris $rn =~ tr/_[A-Z]/ [a-z]/; 68959191Skris } 690280304Sjkim if(length($i) + length($rn) > 56) { 691280304Sjkim print OUT " {${rstr},\n \"$rn\"},\n"; 692280304Sjkim } else { 693280304Sjkim print OUT " {${rstr}, \"$rn\"},\n"; 694280304Sjkim } 69555714Skris } 69655714Skrisif($static) { 69755714Skris print OUT <<"EOF"; 698280304Sjkim {0, NULL} 699280304Sjkim}; 70055714Skris 70155714Skris#endif 70255714Skris 703109998Smarkm${staticloader}void ERR_load_${lib}_strings(void) 704280304Sjkim{ 705167612Ssimon#ifndef OPENSSL_NO_ERR 70655714Skris 707280304Sjkim if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) { 708280304Sjkim ERR_load_strings($load_errcode, ${lib}_str_functs); 709280304Sjkim ERR_load_strings($load_errcode, ${lib}_str_reasons); 710280304Sjkim } 71155714Skris#endif 712280304Sjkim} 71355714SkrisEOF 71455714Skris} else { 71555714Skris print OUT <<"EOF"; 716280304Sjkim {0, NULL} 717280304Sjkim}; 71855714Skris 71955714Skris#endif 72055714Skris 72155714Skris#ifdef ${lib}_LIB_NAME 722280304Sjkimstatic ERR_STRING_DATA ${lib}_lib_name[] = { 723280304Sjkim {0, ${lib}_LIB_NAME}, 724280304Sjkim {0, NULL} 725280304Sjkim}; 72655714Skris#endif 72755714Skris 728280304Sjkimstatic int ${lib}_lib_error_code = 0; 729280304Sjkimstatic int ${lib}_error_init = 1; 73055714Skris 731109998Smarkm${staticloader}void ERR_load_${lib}_strings(void) 732280304Sjkim{ 733280304Sjkim if (${lib}_lib_error_code == 0) 734280304Sjkim ${lib}_lib_error_code = ERR_get_next_error_library(); 73555714Skris 736280304Sjkim if (${lib}_error_init) { 737280304Sjkim ${lib}_error_init = 0; 738109998Smarkm#ifndef OPENSSL_NO_ERR 739280304Sjkim ERR_load_strings(${lib}_lib_error_code, ${lib}_str_functs); 740280304Sjkim ERR_load_strings(${lib}_lib_error_code, ${lib}_str_reasons); 74155714Skris#endif 74255714Skris 74355714Skris#ifdef ${lib}_LIB_NAME 744280304Sjkim ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code, 0, 0); 745280304Sjkim ERR_load_strings(0, ${lib}_lib_name); 74659191Skris#endif 747280304Sjkim } 748280304Sjkim} 74955714Skris 750109998Smarkm${staticloader}void ERR_unload_${lib}_strings(void) 751280304Sjkim{ 752280304Sjkim if (${lib}_error_init == 0) { 753109998Smarkm#ifndef OPENSSL_NO_ERR 754280304Sjkim ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_functs); 755280304Sjkim ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_reasons); 756109998Smarkm#endif 757109998Smarkm 758109998Smarkm#ifdef ${lib}_LIB_NAME 759280304Sjkim ERR_unload_strings(0, ${lib}_lib_name); 760109998Smarkm#endif 761280304Sjkim ${lib}_error_init = 1; 762280304Sjkim } 763280304Sjkim} 764109998Smarkm 765109998Smarkm${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line) 766280304Sjkim{ 767280304Sjkim if (${lib}_lib_error_code == 0) 768280304Sjkim ${lib}_lib_error_code = ERR_get_next_error_library(); 769280304Sjkim ERR_PUT_error(${lib}_lib_error_code, function, reason, file, line); 770280304Sjkim} 77155714SkrisEOF 77255714Skris 77355714Skris} 77455714Skris 77555714Skris close OUT; 77659191Skris undef %err_reason_strings; 77755714Skris} 77855714Skris 779237657Sjkimif($debug && %notrans) { 78055714Skris print STDERR "The following function codes were not translated:\n"; 78155714Skris foreach(sort keys %notrans) 78255714Skris { 78355714Skris print STDERR "$_\n"; 78455714Skris } 78555714Skris} 78655714Skris 78755714Skris# Make a list of unreferenced function and reason codes 78855714Skris 78955714Skrisforeach (keys %fcodes) { 79055714Skris push (@funref, $_) unless exists $ufcodes{$_}; 79155714Skris} 79255714Skris 79355714Skrisforeach (keys %rcodes) { 79455714Skris push (@runref, $_) unless exists $urcodes{$_}; 79555714Skris} 79655714Skris 797269686Sjkimif($debug && @funref) { 79855714Skris print STDERR "The following function codes were not referenced:\n"; 79955714Skris foreach(sort @funref) 80055714Skris { 80155714Skris print STDERR "$_\n"; 80255714Skris } 80355714Skris} 80455714Skris 805269686Sjkimif($debug && @runref) { 80655714Skris print STDERR "The following reason codes were not referenced:\n"; 80755714Skris foreach(sort @runref) 80855714Skris { 80955714Skris print STDERR "$_\n"; 81055714Skris } 81155714Skris} 812238405Sjkim 813238405Sjkimif($errcount) { 814238405Sjkim print STDERR "There were errors, failing...\n\n"; 815238405Sjkim exit $errcount; 816238405Sjkim} 817238405Sjkim 818