155714Skris#!/usr/local/bin/perl -w
255714Skris
355714Skrismy $config = "crypto/err/openssl.ec";
455714Skrismy $debug = 0;
555714Skrismy $rebuild = 0;
655714Skrismy $static = 1;
755714Skrismy $recurse = 0;
855714Skrismy $reindex = 0;
955714Skrismy $dowrite = 0;
10109998Smarkmmy $staticloader = "";
1155714Skris
12160814Ssimonmy $pack_errcode;
13160814Ssimonmy $load_errcode;
14160814Ssimon
1555714Skriswhile (@ARGV) {
1655714Skris	my $arg = $ARGV[0];
1755714Skris	if($arg eq "-conf") {
1855714Skris		shift @ARGV;
1955714Skris		$config = shift @ARGV;
2055714Skris	} elsif($arg eq "-debug") {
2155714Skris		$debug = 1;
2255714Skris		shift @ARGV;
2355714Skris	} elsif($arg eq "-rebuild") {
2455714Skris		$rebuild = 1;
2555714Skris		shift @ARGV;
2655714Skris	} elsif($arg eq "-recurse") {
2755714Skris		$recurse = 1;
2855714Skris		shift @ARGV;
2955714Skris	} elsif($arg eq "-reindex") {
3055714Skris		$reindex = 1;
3155714Skris		shift @ARGV;
3255714Skris	} elsif($arg eq "-nostatic") {
3355714Skris		$static = 0;
3455714Skris		shift @ARGV;
35109998Smarkm	} elsif($arg eq "-staticloader") {
36109998Smarkm		$staticloader = "static ";
37109998Smarkm		shift @ARGV;
3855714Skris	} elsif($arg eq "-write") {
3955714Skris		$dowrite = 1;
4055714Skris		shift @ARGV;
4155714Skris	} else {
4255714Skris		last;
4355714Skris	}
4455714Skris}
4555714Skris
4655714Skrisif($recurse) {
47194206Ssimon	@source = ( <crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>,
48194206Ssimon			<fips/*.c>, <fips/*/*.c>);
4955714Skris} else {
5055714Skris	@source = @ARGV;
5155714Skris}
5255714Skris
5355714Skris# Read in the config file
5455714Skris
5555714Skrisopen(IN, "<$config") || die "Can't open config file $config";
5655714Skris
5755714Skris# Parse config file
5855714Skris
5955714Skriswhile(<IN>)
6055714Skris{
6155714Skris	if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
6255714Skris		$hinc{$1} = $2;
6389837Skris		$libinc{$2} = $1;
6455714Skris		$cskip{$3} = $1;
6555714Skris		if($3 ne "NONE") {
6655714Skris			$csrc{$1} = $3;
6755714Skris			$fmax{$1} = 99;
6855714Skris			$rmax{$1} = 99;
69160814Ssimon			$fassigned{$1} = ":";
70160814Ssimon			$rassigned{$1} = ":";
7155714Skris			$fnew{$1} = 0;
7255714Skris			$rnew{$1} = 0;
7355714Skris		}
7455714Skris	} elsif (/^F\s+(\S+)/) {
7555714Skris	# Add extra function with $1
7655714Skris	} elsif (/^R\s+(\S+)\s+(\S+)/) {
7755714Skris		$rextra{$1} = $2;
7855714Skris		$rcodes{$1} = $2;
7955714Skris	}
8055714Skris}
8155714Skris
8255714Skrisclose IN;
8355714Skris
8455714Skris# Scan each header file in turn and make a list of error codes
8555714Skris# and function names
8655714Skris
8789837Skriswhile (($hdr, $lib) = each %libinc)
8855714Skris{
8955714Skris	next if($hdr eq "NONE");
9055714Skris	print STDERR "Scanning header file $hdr\n" if $debug;
91109998Smarkm	my $line = "", $def= "", $linenr = 0, $gotfile = 0;
92109998Smarkm	if (open(IN, "<$hdr")) {
93109998Smarkm	    $gotfile = 1;
94109998Smarkm	    while(<IN>) {
95109998Smarkm		$linenr++;
96109998Smarkm		print STDERR "line: $linenr\r" if $debug;
9768651Skris
98109998Smarkm		last if(/BEGIN\s+ERROR\s+CODES/);
99109998Smarkm		if ($line ne '') {
100109998Smarkm		    $_ = $line . $_;
101109998Smarkm		    $line = '';
102109998Smarkm		}
10355714Skris
104109998Smarkm		if (/\\$/) {
105109998Smarkm		    $line = $_;
106109998Smarkm		    next;
107109998Smarkm		}
10855714Skris
109160814Ssimon		if(/\/\*/) {
110160814Ssimon		    if (not /\*\//) {		# multiline comment...
111160814Ssimon			$line = $_;		# ... just accumulate
112160814Ssimon			next;
113160814Ssimon		    } else {
114160814Ssimon			s/\/\*.*?\*\///gs;	# wipe it
115160814Ssimon		    }
116160814Ssimon		}
117160814Ssimon
118109998Smarkm		if ($cpp) {
119160814Ssimon		    $cpp++ if /^#\s*if/;
120160814Ssimon		    $cpp-- if /^#\s*endif/;
121109998Smarkm		    next;
122109998Smarkm		}
123160814Ssimon		$cpp = 1 if /^#.*ifdef.*cplusplus/;  # skip "C" declaration
12455714Skris
125109998Smarkm		next if (/^\#/);                      # skip preprocessor directives
12655714Skris
127109998Smarkm		s/{[^{}]*}//gs;                      # ignore {} blocks
12855714Skris
129109998Smarkm		if (/\{|\/\*/) { # Add a } so editor works...
130109998Smarkm		    $line = $_;
131109998Smarkm		} else {
132109998Smarkm		    $def .= $_;
133109998Smarkm		}
13455714Skris	    }
13555714Skris	}
13655714Skris
13768651Skris	print STDERR "                                  \r" if $debug;
13868651Skris        $defnr = 0;
139167612Ssimon	# Delete any DECLARE_ macros
140167612Ssimon	$def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
14155714Skris	foreach (split /;/, $def) {
14268651Skris	    $defnr++;
14368651Skris	    print STDERR "def: $defnr\r" if $debug;
14468651Skris
145160814Ssimon	    # The goal is to collect function names from function declarations.
146160814Ssimon
14755714Skris	    s/^[\n\s]*//g;
14855714Skris	    s/[\n\s]*$//g;
149160814Ssimon
150160814Ssimon	    # Skip over recognized non-function declarations
151160814Ssimon	    next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
152160814Ssimon
153167612Ssimon	    # Remove STACK_OF(foo)
154167612Ssimon	    s/STACK_OF\(\w+\)/void/;
155167612Ssimon
156160814Ssimon	    # Reduce argument lists to empty ()
157160814Ssimon	    # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
158160814Ssimon	    while(/\(.*\)/s) {
159160814Ssimon		s/\([^\(\)]+\)/\{\}/gs;
160160814Ssimon		s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs;	#(*f{}) -> f
161160814Ssimon	    }
162160814Ssimon	    # pretend as we didn't use curly braces: {} -> ()
163160814Ssimon	    s/\{\}/\(\)/gs;
164160814Ssimon
165160814Ssimon	    if (/(\w+)\s*\(\).*/s) {	# first token prior [first] () is
166160814Ssimon		my $name = $1;		# a function name!
16755714Skris		$name =~ tr/[a-z]/[A-Z]/;
16855714Skris		$ftrans{$name} = $1;
169160814Ssimon	    } elsif (/[\(\)]/ and not (/=/)) {
17055714Skris		print STDERR "Header $hdr: cannot parse: $_;\n";
17155714Skris	    }
17255714Skris	}
17355714Skris
17468651Skris	print STDERR "                                  \r" if $debug;
17568651Skris
17655714Skris	next if $reindex;
17755714Skris
17855714Skris	# Scan function and reason codes and store them: keep a note of the
17955714Skris	# maximum code used.
18055714Skris
181109998Smarkm	if ($gotfile) {
182160814Ssimon	  while(<IN>) {
183296465Sdelphij		if(/^\#\s*define\s+(\S+)\s+(\S+)/) {
18455714Skris			$name = $1;
18555714Skris			$code = $2;
186109998Smarkm			next if $name =~ /^${lib}err/;
18755714Skris			unless($name =~ /^${lib}_([RF])_(\w+)$/) {
18855714Skris				print STDERR "Invalid error code $name\n";
18955714Skris				next;
19055714Skris			}
19155714Skris			if($1 eq "R") {
19255714Skris				$rcodes{$name} = $code;
193160814Ssimon				if ($rassigned{$lib} =~ /:$code:/) {
194160814Ssimon					print STDERR "!! ERROR: $lib reason code $code assigned twice\n";
195160814Ssimon				}
196160814Ssimon				$rassigned{$lib} .= "$code:";
19755714Skris				if(!(exists $rextra{$name}) &&
19855714Skris					 ($code > $rmax{$lib}) ) {
19955714Skris					$rmax{$lib} = $code;
20055714Skris				}
20155714Skris			} else {
202160814Ssimon				if ($fassigned{$lib} =~ /:$code:/) {
203160814Ssimon					print STDERR "!! ERROR: $lib function code $code assigned twice\n";
204160814Ssimon				}
205160814Ssimon				$fassigned{$lib} .= "$code:";
20655714Skris				if($code > $fmax{$lib}) {
20755714Skris					$fmax{$lib} = $code;
20855714Skris				}
20955714Skris				$fcodes{$name} = $code;
21055714Skris			}
21155714Skris		}
212160814Ssimon	  }
21355714Skris	}
214160814Ssimon
215160814Ssimon	if ($debug) {
216160814Ssimon		if (defined($fmax{$lib})) {
217160814Ssimon			print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
218160814Ssimon			$fassigned{$lib} =~ m/^:(.*):$/;
219160814Ssimon			@fassigned = sort {$a <=> $b} split(":", $1);
220160814Ssimon			print STDERR "  @fassigned\n";
221160814Ssimon		}
222160814Ssimon		if (defined($rmax{$lib})) {
223160814Ssimon			print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
224160814Ssimon			$rassigned{$lib} =~ m/^:(.*):$/;
225160814Ssimon			@rassigned = sort {$a <=> $b} split(":", $1);
226160814Ssimon			print STDERR "  @rassigned\n";
227160814Ssimon		}
228160814Ssimon	}
229160814Ssimon
230160814Ssimon	if ($lib eq "SSL") {
231160814Ssimon		if ($rmax{$lib} >= 1000) {
232160814Ssimon			print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
233160814Ssimon			print STDERR "!!        Any new alerts must be added to $config.\n";
234160814Ssimon			print STDERR "\n";
235160814Ssimon		}
236160814Ssimon	}
23755714Skris	close IN;
23855714Skris}
23955714Skris
24055714Skris# Scan each C source file and look for function and reason codes
24155714Skris# This is done by looking for strings that "look like" function or
24255714Skris# reason codes: basically anything consisting of all upper case and
24355714Skris# numerics which has _F_ or _R_ in it and which has the name of an
24455714Skris# error library at the start. This seems to work fine except for the
24555714Skris# oddly named structure BIO_F_CTX which needs to be ignored.
24655714Skris# If a code doesn't exist in list compiled from headers then mark it
24755714Skris# with the value "X" as a place holder to give it a value later.
24855714Skris# Store all function and reason codes found in %ufcodes and %urcodes
24955714Skris# so all those unreferenced can be printed out.
25055714Skris
25155714Skris
25255714Skrisforeach $file (@source) {
25355714Skris	# Don't parse the error source file.
25455714Skris	next if exists $cskip{$file};
255160814Ssimon	print STDERR "File loaded: ".$file."\r" if $debug;
25655714Skris	open(IN, "<$file") || die "Can't open source file $file\n";
25755714Skris	while(<IN>) {
25855714Skris		if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
25955714Skris			next unless exists $csrc{$2};
26055714Skris			next if($1 eq "BIO_F_BUFFER_CTX");
26155714Skris			$ufcodes{$1} = 1;
26255714Skris			if(!exists $fcodes{$1}) {
26355714Skris				$fcodes{$1} = "X";
26455714Skris				$fnew{$2}++;
26555714Skris			}
26655714Skris			$notrans{$1} = 1 unless exists $ftrans{$3};
26755714Skris		}
26855714Skris		if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
26955714Skris			next unless exists $csrc{$2};
27055714Skris			$urcodes{$1} = 1;
27155714Skris			if(!exists $rcodes{$1}) {
27255714Skris				$rcodes{$1} = "X";
27355714Skris				$rnew{$2}++;
27455714Skris			}
27555714Skris		}
27655714Skris	}
27755714Skris	close IN;
27855714Skris}
279160814Ssimonprint STDERR "                                  \n" if $debug;
28055714Skris
28155714Skris# Now process each library in turn.
28255714Skris
28355714Skrisforeach $lib (keys %csrc)
28455714Skris{
28555714Skris	my $hfile = $hinc{$lib};
28655714Skris	my $cfile = $csrc{$lib};
28755714Skris	if(!$fnew{$lib} && !$rnew{$lib}) {
28855714Skris		print STDERR "$lib:\t\tNo new error codes\n";
28955714Skris		next unless $rebuild;
29055714Skris	} else {
29155714Skris		print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
29255714Skris		print STDERR " $rnew{$lib} New Reasons.\n";
29355714Skris		next unless $dowrite;
29455714Skris	}
29555714Skris
29655714Skris	# If we get here then we have some new error codes so we
29755714Skris	# need to rebuild the header file and C file.
29855714Skris
29955714Skris	# Make a sorted list of error and reason codes for later use.
30055714Skris
30155714Skris	my @function = sort grep(/^${lib}_/,keys %fcodes);
30255714Skris	my @reasons = sort grep(/^${lib}_/,keys %rcodes);
30355714Skris
30455714Skris	# Rewrite the header file
30555714Skris
306109998Smarkm	if (open(IN, "<$hfile")) {
307109998Smarkm	    # Copy across the old file
308109998Smarkm	    while(<IN>) {
30955714Skris		push @out, $_;
31055714Skris		last if (/BEGIN ERROR CODES/);
311109998Smarkm	    }
312109998Smarkm	    close IN;
313109998Smarkm	} else {
314109998Smarkm	    push @out,
315109998Smarkm"/* ====================================================================\n",
316237998Sjkim" * Copyright (c) 2001-2011 The OpenSSL Project.  All rights reserved.\n",
317109998Smarkm" *\n",
318109998Smarkm" * Redistribution and use in source and binary forms, with or without\n",
319109998Smarkm" * modification, are permitted provided that the following conditions\n",
320109998Smarkm" * are met:\n",
321109998Smarkm" *\n",
322109998Smarkm" * 1. Redistributions of source code must retain the above copyright\n",
323109998Smarkm" *    notice, this list of conditions and the following disclaimer. \n",
324109998Smarkm" *\n",
325109998Smarkm" * 2. Redistributions in binary form must reproduce the above copyright\n",
326109998Smarkm" *    notice, this list of conditions and the following disclaimer in\n",
327109998Smarkm" *    the documentation and/or other materials provided with the\n",
328109998Smarkm" *    distribution.\n",
329109998Smarkm" *\n",
330109998Smarkm" * 3. All advertising materials mentioning features or use of this\n",
331109998Smarkm" *    software must display the following acknowledgment:\n",
332109998Smarkm" *    \"This product includes software developed by the OpenSSL Project\n",
333109998Smarkm" *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
334109998Smarkm" *\n",
335109998Smarkm" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
336109998Smarkm" *    endorse or promote products derived from this software without\n",
337109998Smarkm" *    prior written permission. For written permission, please contact\n",
338109998Smarkm" *    openssl-core\@openssl.org.\n",
339109998Smarkm" *\n",
340109998Smarkm" * 5. Products derived from this software may not be called \"OpenSSL\"\n",
341109998Smarkm" *    nor may \"OpenSSL\" appear in their names without prior written\n",
342109998Smarkm" *    permission of the OpenSSL Project.\n",
343109998Smarkm" *\n",
344109998Smarkm" * 6. Redistributions of any form whatsoever must retain the following\n",
345109998Smarkm" *    acknowledgment:\n",
346109998Smarkm" *    \"This product includes software developed by the OpenSSL Project\n",
347109998Smarkm" *    for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
348109998Smarkm" *\n",
349109998Smarkm" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
350109998Smarkm" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
351109998Smarkm" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
352109998Smarkm" * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
353109998Smarkm" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
354109998Smarkm" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
355109998Smarkm" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
356109998Smarkm" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
357109998Smarkm" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
358109998Smarkm" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
359109998Smarkm" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
360109998Smarkm" * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
361109998Smarkm" * ====================================================================\n",
362109998Smarkm" *\n",
363109998Smarkm" * This product includes cryptographic software written by Eric Young\n",
364109998Smarkm" * (eay\@cryptsoft.com).  This product includes software written by Tim\n",
365109998Smarkm" * Hudson (tjh\@cryptsoft.com).\n",
366109998Smarkm" *\n",
367109998Smarkm" */\n",
368109998Smarkm"\n",
369109998Smarkm"#ifndef HEADER_${lib}_ERR_H\n",
370109998Smarkm"#define HEADER_${lib}_ERR_H\n",
371109998Smarkm"\n",
372109998Smarkm"/* BEGIN ERROR CODES */\n";
37355714Skris	}
37455714Skris	open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
37555714Skris
37655714Skris	print OUT @out;
37755714Skris	undef @out;
37855714Skris	print OUT <<"EOF";
379296465Sdelphij/*
380296465Sdelphij * The following lines are auto generated by the script mkerr.pl. Any changes
38155714Skris * made after this point may be overwritten when the script is next run.
38255714Skris */
383109998SmarkmEOF
384109998Smarkm	if($static) {
385109998Smarkm		print OUT <<"EOF";
386109998Smarkm${staticloader}void ERR_load_${lib}_strings(void);
38755714Skris
388109998SmarkmEOF
389109998Smarkm	} else {
390109998Smarkm		print OUT <<"EOF";
391109998Smarkm${staticloader}void ERR_load_${lib}_strings(void);
392109998Smarkm${staticloader}void ERR_unload_${lib}_strings(void);
393109998Smarkm${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
394296465Sdelphij# define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
395109998Smarkm
396109998SmarkmEOF
397109998Smarkm	}
398109998Smarkm	print OUT <<"EOF";
39955714Skris/* Error codes for the $lib functions. */
40055714Skris
40155714Skris/* Function codes. */
40255714SkrisEOF
40355714Skris
40455714Skris	foreach $i (@function) {
405296465Sdelphij		$z=48 - length($i);
40655714Skris		if($fcodes{$i} eq "X") {
407160814Ssimon			$fassigned{$lib} =~ m/^:([^:]*):/;
408160814Ssimon			$findcode = $1;
409160814Ssimon			if (!defined($findcode)) {
410160814Ssimon				$findcode = $fmax{$lib};
411160814Ssimon			}
412160814Ssimon			while ($fassigned{$lib} =~ m/:$findcode:/) {
413160814Ssimon				$findcode++;
414160814Ssimon			}
415160814Ssimon			$fcodes{$i} = $findcode;
416160814Ssimon			$fassigned{$lib} .= "$findcode:";
41755714Skris			print STDERR "New Function code $i\n" if $debug;
41855714Skris		}
419296465Sdelphij		printf OUT "# define $i%s $fcodes{$i}\n"," " x $z;
42055714Skris	}
42155714Skris
42255714Skris	print OUT "\n/* Reason codes. */\n";
42355714Skris
42455714Skris	foreach $i (@reasons) {
425296465Sdelphij		$z=48 - length($i);
42655714Skris		if($rcodes{$i} eq "X") {
427160814Ssimon			$rassigned{$lib} =~ m/^:([^:]*):/;
428160814Ssimon			$findcode = $1;
429160814Ssimon			if (!defined($findcode)) {
430160814Ssimon				$findcode = $rmax{$lib};
431160814Ssimon			}
432160814Ssimon			while ($rassigned{$lib} =~ m/:$findcode:/) {
433160814Ssimon				$findcode++;
434160814Ssimon			}
435160814Ssimon			$rcodes{$i} = $findcode;
436160814Ssimon			$rassigned{$lib} .= "$findcode:";
43755714Skris			print STDERR "New Reason code   $i\n" if $debug;
43855714Skris		}
439296465Sdelphij		printf OUT "# define $i%s $rcodes{$i}\n"," " x $z;
44055714Skris	}
44155714Skris	print OUT <<"EOF";
44255714Skris
44355714Skris#ifdef  __cplusplus
44455714Skris}
44555714Skris#endif
44655714Skris#endif
44755714SkrisEOF
44855714Skris	close OUT;
44955714Skris
45055714Skris	# Rewrite the C source file containing the error details.
45155714Skris
45259191Skris	# First, read any existing reason string definitions:
45359191Skris	my %err_reason_strings;
45459191Skris	if (open(IN,"<$cfile")) {
455296465Sdelphij		my $line = "";
45659191Skris		while (<IN>) {
457296465Sdelphij			chomp;
458296465Sdelphij			$_ = $line . $_;
459296465Sdelphij			$line = "";
460296465Sdelphij			if (/{ERR_REASON\(/) {
461296465Sdelphij				if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
462296465Sdelphij					$err_reason_strings{$1} = $2;
463296465Sdelphij				} else {
464296465Sdelphij					$line = $_;
465296465Sdelphij				}
46659191Skris			}
46759191Skris		}
46859191Skris		close(IN);
46959191Skris	}
47059191Skris
47155714Skris	my $hincf;
47255714Skris	if($static) {
47355714Skris		$hfile =~ /([^\/]+)$/;
47455714Skris		$hincf = "<openssl/$1>";
47555714Skris	} else {
47655714Skris		$hincf = "\"$hfile\"";
47755714Skris	}
47855714Skris
479160814Ssimon	# If static we know the error code at compile time so use it
480160814Ssimon	# in error definitions.
48155714Skris
482160814Ssimon	if ($static)
483160814Ssimon		{
484160814Ssimon		$pack_errcode = "ERR_LIB_${lib}";
485160814Ssimon		$load_errcode = "0";
486160814Ssimon		}
487160814Ssimon	else
488160814Ssimon		{
489160814Ssimon		$pack_errcode = "0";
490160814Ssimon		$load_errcode = "ERR_LIB_${lib}";
491160814Ssimon		}
492160814Ssimon
493160814Ssimon
49455714Skris	open (OUT,">$cfile") || die "Can't open $cfile for writing";
49555714Skris
49655714Skris	print OUT <<"EOF";
49755714Skris/* $cfile */
49855714Skris/* ====================================================================
499237998Sjkim * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
50055714Skris *
50155714Skris * Redistribution and use in source and binary forms, with or without
50255714Skris * modification, are permitted provided that the following conditions
50355714Skris * are met:
50455714Skris *
50555714Skris * 1. Redistributions of source code must retain the above copyright
506296465Sdelphij *    notice, this list of conditions and the following disclaimer.
50755714Skris *
50855714Skris * 2. Redistributions in binary form must reproduce the above copyright
50955714Skris *    notice, this list of conditions and the following disclaimer in
51055714Skris *    the documentation and/or other materials provided with the
51155714Skris *    distribution.
51255714Skris *
51355714Skris * 3. All advertising materials mentioning features or use of this
51455714Skris *    software must display the following acknowledgment:
51555714Skris *    "This product includes software developed by the OpenSSL Project
51655714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
51755714Skris *
51855714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
51955714Skris *    endorse or promote products derived from this software without
52055714Skris *    prior written permission. For written permission, please contact
52155714Skris *    openssl-core\@OpenSSL.org.
52255714Skris *
52355714Skris * 5. Products derived from this software may not be called "OpenSSL"
52455714Skris *    nor may "OpenSSL" appear in their names without prior written
52555714Skris *    permission of the OpenSSL Project.
52655714Skris *
52755714Skris * 6. Redistributions of any form whatsoever must retain the following
52855714Skris *    acknowledgment:
52955714Skris *    "This product includes software developed by the OpenSSL Project
53055714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
53155714Skris *
53255714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
53355714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53455714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53555714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
53655714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53755714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53855714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53955714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54055714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54155714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54255714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54355714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
54455714Skris * ====================================================================
54555714Skris *
54655714Skris * This product includes cryptographic software written by Eric Young
54755714Skris * (eay\@cryptsoft.com).  This product includes software written by Tim
54855714Skris * Hudson (tjh\@cryptsoft.com).
54955714Skris *
55055714Skris */
55155714Skris
552296465Sdelphij/*
553296465Sdelphij * NOTE: this file was auto generated by the mkerr.pl script: any changes
55459191Skris * made to it will be overwritten when the script next updates this file,
55559191Skris * only reason strings will be preserved.
55655714Skris */
55755714Skris
55855714Skris#include <stdio.h>
55955714Skris#include <openssl/err.h>
56055714Skris#include $hincf
56155714Skris
56255714Skris/* BEGIN ERROR CODES */
563109998Smarkm#ifndef OPENSSL_NO_ERR
564160814Ssimon
565296465Sdelphij# define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
566296465Sdelphij# define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
567160814Ssimon
568296465Sdelphijstatic ERR_STRING_DATA ${lib}_str_functs[] = {
56955714SkrisEOF
57055714Skris	# Add each function code: if a function name is found then use it.
57155714Skris	foreach $i (@function) {
57255714Skris		my $fn;
57355714Skris		$i =~ /^${lib}_F_(\S+)$/;
57455714Skris		$fn = $1;
57555714Skris		if(exists $ftrans{$fn}) {
57655714Skris			$fn = $ftrans{$fn};
57755714Skris		}
578160814Ssimon#		print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
579296465Sdelphij		if(length($i) + length($fn) > 58) {
580296465Sdelphij			print OUT "    {ERR_FUNC($i),\n     \"$fn\"},\n";
581296465Sdelphij		} else {
582296465Sdelphij			print OUT "    {ERR_FUNC($i), \"$fn\"},\n";
583296465Sdelphij		}
58455714Skris	}
58555714Skris	print OUT <<"EOF";
586296465Sdelphij    {0, NULL}
587296465Sdelphij};
58855714Skris
589296465Sdelphijstatic ERR_STRING_DATA ${lib}_str_reasons[] = {
59055714SkrisEOF
59155714Skris	# Add each reason code.
59255714Skris	foreach $i (@reasons) {
59355714Skris		my $rn;
594160814Ssimon		my $rstr = "ERR_REASON($i)";
59559191Skris		if (exists $err_reason_strings{$i}) {
59659191Skris			$rn = $err_reason_strings{$i};
59759191Skris		} else {
59859191Skris			$i =~ /^${lib}_R_(\S+)$/;
59959191Skris			$rn = $1;
60059191Skris			$rn =~ tr/_[A-Z]/ [a-z]/;
60159191Skris		}
602296465Sdelphij		if(length($i) + length($rn) > 56) {
603296465Sdelphij			print OUT "    {${rstr},\n     \"$rn\"},\n";
604296465Sdelphij		} else {
605296465Sdelphij			print OUT "    {${rstr}, \"$rn\"},\n";
606296465Sdelphij		}
60755714Skris	}
60855714Skrisif($static) {
60955714Skris	print OUT <<"EOF";
610296465Sdelphij    {0, NULL}
611296465Sdelphij};
61255714Skris
61355714Skris#endif
61455714Skris
615109998Smarkm${staticloader}void ERR_load_${lib}_strings(void)
616296465Sdelphij{
617167612Ssimon#ifndef OPENSSL_NO_ERR
61855714Skris
619296465Sdelphij    if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) {
620296465Sdelphij        ERR_load_strings($load_errcode, ${lib}_str_functs);
621296465Sdelphij        ERR_load_strings($load_errcode, ${lib}_str_reasons);
622296465Sdelphij    }
62355714Skris#endif
624296465Sdelphij}
62555714SkrisEOF
62655714Skris} else {
62755714Skris	print OUT <<"EOF";
628296465Sdelphij    {0, NULL}
629296465Sdelphij};
63055714Skris
63155714Skris#endif
63255714Skris
63355714Skris#ifdef ${lib}_LIB_NAME
634296465Sdelphijstatic ERR_STRING_DATA ${lib}_lib_name[] = {
635296465Sdelphij    {0, ${lib}_LIB_NAME},
636296465Sdelphij    {0, NULL}
637296465Sdelphij};
63855714Skris#endif
63955714Skris
640296465Sdelphijstatic int ${lib}_lib_error_code = 0;
641296465Sdelphijstatic int ${lib}_error_init = 1;
64255714Skris
643109998Smarkm${staticloader}void ERR_load_${lib}_strings(void)
644296465Sdelphij{
645296465Sdelphij    if (${lib}_lib_error_code == 0)
646296465Sdelphij        ${lib}_lib_error_code = ERR_get_next_error_library();
64755714Skris
648296465Sdelphij    if (${lib}_error_init) {
649296465Sdelphij        ${lib}_error_init = 0;
650109998Smarkm#ifndef OPENSSL_NO_ERR
651296465Sdelphij        ERR_load_strings(${lib}_lib_error_code, ${lib}_str_functs);
652296465Sdelphij        ERR_load_strings(${lib}_lib_error_code, ${lib}_str_reasons);
65355714Skris#endif
65455714Skris
65555714Skris#ifdef ${lib}_LIB_NAME
656296465Sdelphij        ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code, 0, 0);
657296465Sdelphij        ERR_load_strings(0, ${lib}_lib_name);
65859191Skris#endif
659296465Sdelphij    }
660296465Sdelphij}
66155714Skris
662109998Smarkm${staticloader}void ERR_unload_${lib}_strings(void)
663296465Sdelphij{
664296465Sdelphij    if (${lib}_error_init == 0) {
665109998Smarkm#ifndef OPENSSL_NO_ERR
666296465Sdelphij        ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_functs);
667296465Sdelphij        ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_reasons);
668109998Smarkm#endif
669109998Smarkm
670109998Smarkm#ifdef ${lib}_LIB_NAME
671296465Sdelphij        ERR_unload_strings(0, ${lib}_lib_name);
672109998Smarkm#endif
673296465Sdelphij        ${lib}_error_init = 1;
674296465Sdelphij    }
675296465Sdelphij}
676109998Smarkm
677109998Smarkm${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
678296465Sdelphij{
679296465Sdelphij    if (${lib}_lib_error_code == 0)
680296465Sdelphij        ${lib}_lib_error_code = ERR_get_next_error_library();
681296465Sdelphij    ERR_PUT_error(${lib}_lib_error_code, function, reason, file, line);
682296465Sdelphij}
68355714SkrisEOF
68455714Skris
68555714Skris}
68655714Skris
68755714Skris	close OUT;
68859191Skris	undef %err_reason_strings;
68955714Skris}
69055714Skris
691237998Sjkimif($debug && %notrans) {
69255714Skris	print STDERR "The following function codes were not translated:\n";
69355714Skris	foreach(sort keys %notrans)
69455714Skris	{
69555714Skris		print STDERR "$_\n";
69655714Skris	}
69755714Skris}
69855714Skris
69955714Skris# Make a list of unreferenced function and reason codes
70055714Skris
70155714Skrisforeach (keys %fcodes) {
70255714Skris	push (@funref, $_) unless exists $ufcodes{$_};
70355714Skris}
70455714Skris
70555714Skrisforeach (keys %rcodes) {
70655714Skris	push (@runref, $_) unless exists $urcodes{$_};
70755714Skris}
70855714Skris
709279265Sdelphijif($debug && @funref) {
71055714Skris	print STDERR "The following function codes were not referenced:\n";
71155714Skris	foreach(sort @funref)
71255714Skris	{
71355714Skris		print STDERR "$_\n";
71455714Skris	}
71555714Skris}
71655714Skris
717279265Sdelphijif($debug && @runref) {
71855714Skris	print STDERR "The following reason codes were not referenced:\n";
71955714Skris	foreach(sort @runref)
72055714Skris	{
72155714Skris		print STDERR "$_\n";
72255714Skris	}
72355714Skris}
724