make update
[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 } else {
121         @source = @ARGV;
122 }
123
124 # Read in the config file
125
126 open(IN, "<$config") || die "Can't open config file $config";
127
128 # Parse config file
129
130 while(<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
153 close IN;
154
155 # Scan each header file in turn and make a list of error codes
156 # and function names
157
158 while (($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;
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
326 foreach $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 }
358 print STDERR "                                  \n" if $debug;
359
360 # Now process each library in turn.
361
362 foreach $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         if (open(IN, "<$hfile")) {
386             # Copy across the old file
387             while(<IN>) {
388                 push @out, $_;
389                 last if (/BEGIN ERROR CODES/);
390             }
391             close IN;
392         } else {
393             push @out,
394 "/* ====================================================================\n",
395 " * Copyright (c) 2001-$year The OpenSSL Project.  All rights reserved.\n",
396 " *\n",
397 " * Redistribution and use in source and binary forms, with or without\n",
398 " * modification, are permitted provided that the following conditions\n",
399 " * are met:\n",
400 " *\n",
401 " * 1. Redistributions of source code must retain the above copyright\n",
402 " *    notice, this list of conditions and the following disclaimer. \n",
403 " *\n",
404 " * 2. Redistributions in binary form must reproduce the above copyright\n",
405 " *    notice, this list of conditions and the following disclaimer in\n",
406 " *    the documentation and/or other materials provided with the\n",
407 " *    distribution.\n",
408 " *\n",
409 " * 3. All advertising materials mentioning features or use of this\n",
410 " *    software must display the following acknowledgment:\n",
411 " *    \"This product includes software developed by the OpenSSL Project\n",
412 " *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
413 " *\n",
414 " * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
415 " *    endorse or promote products derived from this software without\n",
416 " *    prior written permission. For written permission, please contact\n",
417 " *    openssl-core\@openssl.org.\n",
418 " *\n",
419 " * 5. Products derived from this software may not be called \"OpenSSL\"\n",
420 " *    nor may \"OpenSSL\" appear in their names without prior written\n",
421 " *    permission of the OpenSSL Project.\n",
422 " *\n",
423 " * 6. Redistributions of any form whatsoever must retain the following\n",
424 " *    acknowledgment:\n",
425 " *    \"This product includes software developed by the OpenSSL Project\n",
426 " *    for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
427 " *\n",
428 " * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
429 " * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
430 " * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
431 " * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
432 " * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
433 " * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
434 " * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
435 " * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
436 " * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
437 " * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
438 " * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
439 " * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
440 " * ====================================================================\n",
441 " *\n",
442 " * This product includes cryptographic software written by Eric Young\n",
443 " * (eay\@cryptsoft.com).  This product includes software written by Tim\n",
444 " * Hudson (tjh\@cryptsoft.com).\n",
445 " *\n",
446 " */\n",
447 "\n",
448 "#ifndef HEADER_${lib}_ERR_H\n",
449 "#define HEADER_${lib}_ERR_H\n",
450 "\n",
451 "#ifdef  __cplusplus\n",
452 "extern \"C\" {\n",
453 "#endif\n",
454 "\n",
455 "/* BEGIN ERROR CODES */\n";
456         }
457         open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
458
459         print OUT @out;
460         undef @out;
461         print OUT <<"EOF";
462 /*
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=48 - length($i);
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"," " x $z;
503         }
504
505         print OUT "\n/* Reason codes. */\n";
506
507         foreach $i (@reasons) {
508                 $z=48 - length($i);
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"," " 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                 my $line = "";
539                 while (<IN>) {
540                         chomp;
541                         $_ = $line . $_;
542                         $line = "";
543                         if (/{ERR_(FUNC|REASON)\(/) {
544                                 if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
545                                         $err_reason_strings{$1} = $2;
546                                 } elsif (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
547                                         if (!exists $ftrans{$1} && ($1 ne $2)) {
548                                                 print STDERR "WARNING: Mismatched function string $2\n";
549                                                 $ftrans{$1} = $2;
550                                         }
551                                 } else {
552                                         $line = $_;
553                                 }
554                         }
555                 }
556                 close(IN);
557         }
558
559
560         my $hincf;
561         if($static) {
562                 $hfile =~ /([^\/]+)$/;
563                 $hincf = "<${hprefix}$1>";
564         } else {
565                 $hincf = "\"$hfile\"";
566         }
567
568         # If static we know the error code at compile time so use it
569         # in error definitions.
570
571         if ($static)
572                 {
573                 $pack_errcode = "ERR_LIB_${lib}";
574                 $load_errcode = "0";
575                 }
576         else
577                 {
578                 $pack_errcode = "0";
579                 $load_errcode = "ERR_LIB_${lib}";
580                 }
581
582
583         open (OUT,">$cfile") || die "Can't open $cfile for writing";
584
585         print OUT <<"EOF";
586 /* $cfile */
587 /* ====================================================================
588  * Copyright (c) 1999-$year The OpenSSL Project.  All rights reserved.
589  *
590  * Redistribution and use in source and binary forms, with or without
591  * modification, are permitted provided that the following conditions
592  * are met:
593  *
594  * 1. Redistributions of source code must retain the above copyright
595  *    notice, this list of conditions and the following disclaimer.
596  *
597  * 2. Redistributions in binary form must reproduce the above copyright
598  *    notice, this list of conditions and the following disclaimer in
599  *    the documentation and/or other materials provided with the
600  *    distribution.
601  *
602  * 3. All advertising materials mentioning features or use of this
603  *    software must display the following acknowledgment:
604  *    "This product includes software developed by the OpenSSL Project
605  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
606  *
607  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
608  *    endorse or promote products derived from this software without
609  *    prior written permission. For written permission, please contact
610  *    openssl-core\@OpenSSL.org.
611  *
612  * 5. Products derived from this software may not be called "OpenSSL"
613  *    nor may "OpenSSL" appear in their names without prior written
614  *    permission of the OpenSSL Project.
615  *
616  * 6. Redistributions of any form whatsoever must retain the following
617  *    acknowledgment:
618  *    "This product includes software developed by the OpenSSL Project
619  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
620  *
621  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
622  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
623  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
624  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
625  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
626  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
627  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
628  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
629  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
630  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
631  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
632  * OF THE POSSIBILITY OF SUCH DAMAGE.
633  * ====================================================================
634  *
635  * This product includes cryptographic software written by Eric Young
636  * (eay\@cryptsoft.com).  This product includes software written by Tim
637  * Hudson (tjh\@cryptsoft.com).
638  *
639  */
640
641 /*
642  * NOTE: this file was auto generated by the mkerr.pl script: any changes
643  * made to it will be overwritten when the script next updates this file,
644  * only reason strings will be preserved.
645  */
646
647 #include <stdio.h>
648 #include <openssl/err.h>
649 #include $hincf
650
651 /* BEGIN ERROR CODES */
652 #ifndef OPENSSL_NO_ERR
653
654 # define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
655 # define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
656
657 static ERR_STRING_DATA ${lib}_str_functs[] = {
658 EOF
659         # Add each function code: if a function name is found then use it.
660         foreach $i (@function) {
661                 my $fn;
662                 $i =~ /^${lib}_F_(\S+)$/;
663                 $fn = $1;
664                 if(exists $ftrans{$fn}) {
665                         $fn = $ftrans{$fn};
666                 }
667 #               print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
668                 if(length($i) + length($fn) > 58) {
669                         print OUT "    {ERR_FUNC($i),\n     \"$fn\"},\n";
670                 } else {
671                         print OUT "    {ERR_FUNC($i), \"$fn\"},\n";
672                 }
673         }
674         print OUT <<"EOF";
675     {0, NULL}
676 };
677
678 static ERR_STRING_DATA ${lib}_str_reasons[] = {
679 EOF
680         # Add each reason code.
681         foreach $i (@reasons) {
682                 my $rn;
683                 my $rstr = "ERR_REASON($i)";
684                 if (exists $err_reason_strings{$i}) {
685                         $rn = $err_reason_strings{$i};
686                 } else {
687                         $i =~ /^${lib}_R_(\S+)$/;
688                         $rn = $1;
689                         $rn =~ tr/_[A-Z]/ [a-z]/;
690                 }
691                 if(length($i) + length($rn) > 56) {
692                         print OUT "    {${rstr},\n     \"$rn\"},\n";
693                 } else {
694                         print OUT "    {${rstr}, \"$rn\"},\n";
695                 }
696         }
697 if($static) {
698         print OUT <<"EOF";
699     {0, NULL}
700 };
701
702 #endif
703
704 ${staticloader}void ERR_load_${lib}_strings(void)
705 {
706 #ifndef OPENSSL_NO_ERR
707
708     if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) {
709         ERR_load_strings($load_errcode, ${lib}_str_functs);
710         ERR_load_strings($load_errcode, ${lib}_str_reasons);
711     }
712 #endif
713 }
714 EOF
715 } else {
716         print OUT <<"EOF";
717     {0, NULL}
718 };
719
720 #endif
721
722 #ifdef ${lib}_LIB_NAME
723 static ERR_STRING_DATA ${lib}_lib_name[] = {
724     {0, ${lib}_LIB_NAME},
725     {0, NULL}
726 };
727 #endif
728
729 static int ${lib}_lib_error_code = 0;
730 static int ${lib}_error_init = 1;
731
732 ${staticloader}void ERR_load_${lib}_strings(void)
733 {
734     if (${lib}_lib_error_code == 0)
735         ${lib}_lib_error_code = ERR_get_next_error_library();
736
737     if (${lib}_error_init) {
738         ${lib}_error_init = 0;
739 #ifndef OPENSSL_NO_ERR
740         ERR_load_strings(${lib}_lib_error_code, ${lib}_str_functs);
741         ERR_load_strings(${lib}_lib_error_code, ${lib}_str_reasons);
742 #endif
743
744 #ifdef ${lib}_LIB_NAME
745         ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code, 0, 0);
746         ERR_load_strings(0, ${lib}_lib_name);
747 #endif
748     }
749 }
750
751 ${staticloader}void ERR_unload_${lib}_strings(void)
752 {
753     if (${lib}_error_init == 0) {
754 #ifndef OPENSSL_NO_ERR
755         ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_functs);
756         ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_reasons);
757 #endif
758
759 #ifdef ${lib}_LIB_NAME
760         ERR_unload_strings(0, ${lib}_lib_name);
761 #endif
762         ${lib}_error_init = 1;
763     }
764 }
765
766 ${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
767 {
768     if (${lib}_lib_error_code == 0)
769         ${lib}_lib_error_code = ERR_get_next_error_library();
770     ERR_PUT_error(${lib}_lib_error_code, function, reason, file, line);
771 }
772 EOF
773
774 }
775
776         close OUT;
777         undef %err_reason_strings;
778 }
779
780 if($debug && %notrans) {
781         print STDERR "The following function codes were not translated:\n";
782         foreach(sort keys %notrans)
783         {
784                 print STDERR "$_\n";
785         }
786 }
787
788 # Make a list of unreferenced function and reason codes
789
790 foreach (keys %fcodes) {
791         push (@funref, $_) unless exists $ufcodes{$_};
792 }
793
794 foreach (keys %rcodes) {
795         push (@runref, $_) unless exists $urcodes{$_};
796 }
797
798 if($debug && @funref) {
799         print STDERR "The following function codes were not referenced:\n";
800         foreach(sort @funref)
801         {
802                 print STDERR "$_\n";
803         }
804 }
805
806 if($debug && @runref) {
807         print STDERR "The following reason codes were not referenced:\n";
808         foreach(sort @runref)
809         {
810                 print STDERR "$_\n";
811         }
812 }
813
814 if($errcount) {
815         print STDERR "There were errors, failing...\n\n";
816         exit $errcount;
817 }
818