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