Remove extraneous output from util/mk scripts
[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,__FILE__,__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),__FILE__,__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                         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 /* $cfile */
606 /* ====================================================================
607  * Copyright (c) 1999-$year The OpenSSL Project.  All rights reserved.
608  *
609  * Redistribution and use in source and binary forms, with or without
610  * modification, are permitted provided that the following conditions
611  * are met:
612  *
613  * 1. Redistributions of source code must retain the above copyright
614  *    notice, this list of conditions and the following disclaimer.
615  *
616  * 2. Redistributions in binary form must reproduce the above copyright
617  *    notice, this list of conditions and the following disclaimer in
618  *    the documentation and/or other materials provided with the
619  *    distribution.
620  *
621  * 3. All advertising materials mentioning features or use of this
622  *    software must display the following acknowledgment:
623  *    "This product includes software developed by the OpenSSL Project
624  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
625  *
626  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
627  *    endorse or promote products derived from this software without
628  *    prior written permission. For written permission, please contact
629  *    openssl-core\@OpenSSL.org.
630  *
631  * 5. Products derived from this software may not be called "OpenSSL"
632  *    nor may "OpenSSL" appear in their names without prior written
633  *    permission of the OpenSSL Project.
634  *
635  * 6. Redistributions of any form whatsoever must retain the following
636  *    acknowledgment:
637  *    "This product includes software developed by the OpenSSL Project
638  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
639  *
640  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
641  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
642  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
643  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
644  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
645  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
646  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
647  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
648  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
649  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
650  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
651  * OF THE POSSIBILITY OF SUCH DAMAGE.
652  * ====================================================================
653  *
654  * This product includes cryptographic software written by Eric Young
655  * (eay\@cryptsoft.com).  This product includes software written by Tim
656  * Hudson (tjh\@cryptsoft.com).
657  *
658  */
659
660 /*
661  * NOTE: this file was auto generated by the mkerr.pl script: any changes
662  * made to it will be overwritten when the script next updates this file,
663  * only reason strings will be preserved.
664  */
665
666 #include <stdio.h>
667 #include <openssl/err.h>
668 #include $hincf
669
670 /* BEGIN ERROR CODES */
671 #ifndef OPENSSL_NO_ERR
672
673 # define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
674 # define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
675
676 static ERR_STRING_DATA ${lib}_str_functs[] = {
677 EOF
678         # Add each function code: if a function name is found then use it.
679         foreach $i (@function) {
680                 my $fn;
681                 $i =~ /^${lib}_F_(\S+)$/;
682                 $fn = $1;
683                 if(exists $ftrans{$fn}) {
684                         $fn = $ftrans{$fn};
685                 }
686 #               print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
687                 if(length($i) + length($fn) > 58) {
688                         print OUT "    {ERR_FUNC($i),\n     \"$fn\"},\n";
689                 } else {
690                         print OUT "    {ERR_FUNC($i), \"$fn\"},\n";
691                 }
692         }
693         print OUT <<"EOF";
694     {0, NULL}
695 };
696
697 static ERR_STRING_DATA ${lib}_str_reasons[] = {
698 EOF
699         # Add each reason code.
700         foreach $i (@reasons) {
701                 my $rn;
702                 my $rstr = "ERR_REASON($i)";
703                 if (exists $err_reason_strings{$i}) {
704                         $rn = $err_reason_strings{$i};
705                 } else {
706                         $i =~ /^${lib}_R_(\S+)$/;
707                         $rn = $1;
708                         $rn =~ tr/_[A-Z]/ [a-z]/;
709                 }
710                 if(length($i) + length($rn) > 56) {
711                         print OUT "    {${rstr},\n     \"$rn\"},\n";
712                 } else {
713                         print OUT "    {${rstr}, \"$rn\"},\n";
714                 }
715         }
716 if($static) {
717         print OUT <<"EOF";
718     {0, NULL}
719 };
720
721 #endif
722
723 ${staticloader}void ERR_load_${lib}_strings(void)
724 {
725 #ifndef OPENSSL_NO_ERR
726
727     if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) {
728         ERR_load_strings($load_errcode, ${lib}_str_functs);
729         ERR_load_strings($load_errcode, ${lib}_str_reasons);
730     }
731 #endif
732 }
733 EOF
734 } else {
735         print OUT <<"EOF";
736     {0, NULL}
737 };
738
739 #endif
740
741 #ifdef ${lib}_LIB_NAME
742 static ERR_STRING_DATA ${lib}_lib_name[] = {
743     {0, ${lib}_LIB_NAME},
744     {0, NULL}
745 };
746 #endif
747
748 static int ${lib}_lib_error_code = 0;
749 static int ${lib}_error_init = 1;
750
751 ${staticloader}void ERR_load_${lib}_strings(void)
752 {
753     if (${lib}_lib_error_code == 0)
754         ${lib}_lib_error_code = ERR_get_next_error_library();
755
756     if (${lib}_error_init) {
757         ${lib}_error_init = 0;
758 #ifndef OPENSSL_NO_ERR
759         ERR_load_strings(${lib}_lib_error_code, ${lib}_str_functs);
760         ERR_load_strings(${lib}_lib_error_code, ${lib}_str_reasons);
761 #endif
762
763 #ifdef ${lib}_LIB_NAME
764         ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code, 0, 0);
765         ERR_load_strings(0, ${lib}_lib_name);
766 #endif
767     }
768 }
769
770 ${staticloader}void ERR_unload_${lib}_strings(void)
771 {
772     if (${lib}_error_init == 0) {
773 #ifndef OPENSSL_NO_ERR
774         ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_functs);
775         ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_reasons);
776 #endif
777
778 #ifdef ${lib}_LIB_NAME
779         ERR_unload_strings(0, ${lib}_lib_name);
780 #endif
781         ${lib}_error_init = 1;
782     }
783 }
784
785 ${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
786 {
787     if (${lib}_lib_error_code == 0)
788         ${lib}_lib_error_code = ERR_get_next_error_library();
789     ERR_PUT_error(${lib}_lib_error_code, function, reason, file, line);
790 }
791 EOF
792
793 }
794
795         close OUT;
796         undef %err_reason_strings;
797 }
798
799 if($debug && %notrans) {
800         print STDERR "The following function codes were not translated:\n";
801         foreach(sort keys %notrans)
802         {
803                 print STDERR "$_\n";
804         }
805 }
806
807 # Make a list of unreferenced function and reason codes
808
809 foreach (keys %fcodes) {
810         push (@funref, $_) unless exists $ufcodes{$_};
811 }
812
813 foreach (keys %rcodes) {
814         push (@runref, $_) unless exists $urcodes{$_};
815 }
816
817 if($unref && @funref) {
818         print STDERR "The following function codes were not referenced:\n";
819         foreach(sort @funref)
820         {
821                 print STDERR "$_\n";
822         }
823 }
824
825 if($unref && @runref) {
826         print STDERR "The following reason codes were not referenced:\n";
827         foreach(sort @runref)
828         {
829                 print STDERR "$_\n";
830         }
831 }
832
833 if($errcount) {
834         print STDERR "There were errors, failing...\n\n";
835         exit $errcount;
836 }
837