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