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