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