source: trunk/third/openssl/util/mkerr.pl @ 18442

Revision 18442, 16.4 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18441, which included commits to RCS files with non-trunk default branches.
Line 
1#!/usr/local/bin/perl -w
2
3my $config = "crypto/err/openssl.ec";
4my $debug = 0;
5my $rebuild = 0;
6my $static = 1;
7my $recurse = 0;
8my $reindex = 0;
9my $dowrite = 0;
10my $staticloader = "";
11
12while (@ARGV) {
13        my $arg = $ARGV[0];
14        if($arg eq "-conf") {
15                shift @ARGV;
16                $config = shift @ARGV;
17        } elsif($arg eq "-debug") {
18                $debug = 1;
19                shift @ARGV;
20        } elsif($arg eq "-rebuild") {
21                $rebuild = 1;
22                shift @ARGV;
23        } elsif($arg eq "-recurse") {
24                $recurse = 1;
25                shift @ARGV;
26        } elsif($arg eq "-reindex") {
27                $reindex = 1;
28                shift @ARGV;
29        } elsif($arg eq "-nostatic") {
30                $static = 0;
31                shift @ARGV;
32        } elsif($arg eq "-staticloader") {
33                $staticloader = "static ";
34                shift @ARGV;
35        } elsif($arg eq "-write") {
36                $dowrite = 1;
37                shift @ARGV;
38        } else {
39                last;
40        }
41}
42
43if($recurse) {
44        @source = (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>);
45} else {
46        @source = @ARGV;
47}
48
49# Read in the config file
50
51open(IN, "<$config") || die "Can't open config file $config";
52
53# Parse config file
54
55while(<IN>)
56{
57        if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
58                $hinc{$1} = $2;
59                $libinc{$2} = $1;
60                $cskip{$3} = $1;
61                if($3 ne "NONE") {
62                        $csrc{$1} = $3;
63                        $fmax{$1} = 99;
64                        $rmax{$1} = 99;
65                        $fnew{$1} = 0;
66                        $rnew{$1} = 0;
67                }
68        } elsif (/^F\s+(\S+)/) {
69        # Add extra function with $1
70        } elsif (/^R\s+(\S+)\s+(\S+)/) {
71                $rextra{$1} = $2;
72                $rcodes{$1} = $2;
73        }
74}
75
76close IN;
77
78# Scan each header file in turn and make a list of error codes
79# and function names
80
81while (($hdr, $lib) = each %libinc)
82{
83        next if($hdr eq "NONE");
84        print STDERR "Scanning header file $hdr\n" if $debug;
85        my $line = "", $def= "", $linenr = 0, $gotfile = 0;
86        if (open(IN, "<$hdr")) {
87            $gotfile = 1;
88            while(<IN>) {
89                $linenr++;
90                print STDERR "line: $linenr\r" if $debug;
91
92                last if(/BEGIN\s+ERROR\s+CODES/);
93                if ($line ne '') {
94                    $_ = $line . $_;
95                    $line = '';
96                }
97
98                if (/\\$/) {
99                    $line = $_;
100                    next;
101                }
102
103                $cpp = 1 if /^#.*ifdef.*cplusplus/;  # skip "C" declaration
104                if ($cpp) {
105                    $cpp = 0 if /^#.*endif/;
106                    next;
107                }
108
109                next if (/^\#/);                      # skip preprocessor directives
110
111                s/\/\*.*?\*\///gs;                   # ignore comments
112                s/{[^{}]*}//gs;                      # ignore {} blocks
113
114                if (/\{|\/\*/) { # Add a } so editor works...
115                    $line = $_;
116                } else {
117                    $def .= $_;
118                }
119            }
120        }
121
122        print STDERR "                                  \r" if $debug;
123        $defnr = 0;
124        foreach (split /;/, $def) {
125            $defnr++;
126            print STDERR "def: $defnr\r" if $debug;
127
128            s/^[\n\s]*//g;
129            s/[\n\s]*$//g;
130            next if(/typedef\W/);
131            if (/\(\*(\w*)\([^\)]+/) {
132                my $name = $1;
133                $name =~ tr/[a-z]/[A-Z]/;
134                $ftrans{$name} = $1;
135            } elsif (/\w+\W+(\w+)\W*\(\s*\)$/s){
136                # K&R C
137                next ;
138            } elsif (/\w+\W+\w+\W*\(.*\)$/s) {
139                while (not /\(\)$/s) {
140                    s/[^\(\)]*\)$/\)/s;
141                    s/\([^\(\)]*\)\)$/\)/s;
142                }
143                s/\(void\)//;
144                /(\w+)\W*\(\)/s;
145                my $name = $1;
146                $name =~ tr/[a-z]/[A-Z]/;
147                $ftrans{$name} = $1;
148            } elsif (/\(/ and not (/=/ or /DECLARE_STACK/)) {
149                print STDERR "Header $hdr: cannot parse: $_;\n";
150            }
151        }
152
153        print STDERR "                                  \r" if $debug;
154
155        next if $reindex;
156
157        # Scan function and reason codes and store them: keep a note of the
158        # maximum code used.
159
160        if ($gotfile) {
161            while(<IN>) {
162                if(/^\#define\s+(\S+)\s+(\S+)/) {
163                        $name = $1;
164                        $code = $2;
165                        next if $name =~ /^${lib}err/;
166                        unless($name =~ /^${lib}_([RF])_(\w+)$/) {
167                                print STDERR "Invalid error code $name\n";
168                                next;
169                        }
170                        if($1 eq "R") {
171                                $rcodes{$name} = $code;
172                                if(!(exists $rextra{$name}) &&
173                                         ($code > $rmax{$lib}) ) {
174                                        $rmax{$lib} = $code;
175                                }
176                        } else {
177                                if($code > $fmax{$lib}) {
178                                        $fmax{$lib} = $code;
179                                }
180                                $fcodes{$name} = $code;
181                        }
182                }
183            }
184        }
185        close IN;
186}
187
188# Scan each C source file and look for function and reason codes
189# This is done by looking for strings that "look like" function or
190# reason codes: basically anything consisting of all upper case and
191# numerics which has _F_ or _R_ in it and which has the name of an
192# error library at the start. This seems to work fine except for the
193# oddly named structure BIO_F_CTX which needs to be ignored.
194# If a code doesn't exist in list compiled from headers then mark it
195# with the value "X" as a place holder to give it a value later.
196# Store all function and reason codes found in %ufcodes and %urcodes
197# so all those unreferenced can be printed out.
198
199
200print STDERR "Files loaded: " if $debug;
201foreach $file (@source) {
202        # Don't parse the error source file.
203        next if exists $cskip{$file};
204        print STDERR $file if $debug;
205        open(IN, "<$file") || die "Can't open source file $file\n";
206        while(<IN>) {
207                if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
208                        next unless exists $csrc{$2};
209                        next if($1 eq "BIO_F_BUFFER_CTX");
210                        $ufcodes{$1} = 1;
211                        if(!exists $fcodes{$1}) {
212                                $fcodes{$1} = "X";
213                                $fnew{$2}++;
214                        }
215                        $notrans{$1} = 1 unless exists $ftrans{$3};
216                }
217                if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
218                        next unless exists $csrc{$2};
219                        $urcodes{$1} = 1;
220                        if(!exists $rcodes{$1}) {
221                                $rcodes{$1} = "X";
222                                $rnew{$2}++;
223                        }
224                }
225        }
226        close IN;
227}
228print STDERR "\n" if $debug;
229
230# Now process each library in turn.
231
232foreach $lib (keys %csrc)
233{
234        my $hfile = $hinc{$lib};
235        my $cfile = $csrc{$lib};
236        if(!$fnew{$lib} && !$rnew{$lib}) {
237                print STDERR "$lib:\t\tNo new error codes\n";
238                next unless $rebuild;
239        } else {
240                print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
241                print STDERR " $rnew{$lib} New Reasons.\n";
242                next unless $dowrite;
243        }
244
245        # If we get here then we have some new error codes so we
246        # need to rebuild the header file and C file.
247
248        # Make a sorted list of error and reason codes for later use.
249
250        my @function = sort grep(/^${lib}_/,keys %fcodes);
251        my @reasons = sort grep(/^${lib}_/,keys %rcodes);
252
253        # Rewrite the header file
254
255        if (open(IN, "<$hfile")) {
256            # Copy across the old file
257            while(<IN>) {
258                push @out, $_;
259                last if (/BEGIN ERROR CODES/);
260            }
261            close IN;
262        } else {
263            push @out,
264"/* ====================================================================\n",
265" * Copyright (c) 2001-2002 The OpenSSL Project.  All rights reserved.\n",
266" *\n",
267" * Redistribution and use in source and binary forms, with or without\n",
268" * modification, are permitted provided that the following conditions\n",
269" * are met:\n",
270" *\n",
271" * 1. Redistributions of source code must retain the above copyright\n",
272" *    notice, this list of conditions and the following disclaimer. \n",
273" *\n",
274" * 2. Redistributions in binary form must reproduce the above copyright\n",
275" *    notice, this list of conditions and the following disclaimer in\n",
276" *    the documentation and/or other materials provided with the\n",
277" *    distribution.\n",
278" *\n",
279" * 3. All advertising materials mentioning features or use of this\n",
280" *    software must display the following acknowledgment:\n",
281" *    \"This product includes software developed by the OpenSSL Project\n",
282" *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
283" *\n",
284" * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
285" *    endorse or promote products derived from this software without\n",
286" *    prior written permission. For written permission, please contact\n",
287" *    openssl-core\@openssl.org.\n",
288" *\n",
289" * 5. Products derived from this software may not be called \"OpenSSL\"\n",
290" *    nor may \"OpenSSL\" appear in their names without prior written\n",
291" *    permission of the OpenSSL Project.\n",
292" *\n",
293" * 6. Redistributions of any form whatsoever must retain the following\n",
294" *    acknowledgment:\n",
295" *    \"This product includes software developed by the OpenSSL Project\n",
296" *    for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
297" *\n",
298" * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
299" * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
300" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
301" * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
302" * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
303" * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
304" * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
305" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
306" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
307" * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
308" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
309" * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
310" * ====================================================================\n",
311" *\n",
312" * This product includes cryptographic software written by Eric Young\n",
313" * (eay\@cryptsoft.com).  This product includes software written by Tim\n",
314" * Hudson (tjh\@cryptsoft.com).\n",
315" *\n",
316" */\n",
317"\n",
318"#ifndef HEADER_${lib}_ERR_H\n",
319"#define HEADER_${lib}_ERR_H\n",
320"\n",
321"/* BEGIN ERROR CODES */\n";
322        }
323        open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
324
325        print OUT @out;
326        undef @out;
327        print OUT <<"EOF";
328/* The following lines are auto generated by the script mkerr.pl. Any changes
329 * made after this point may be overwritten when the script is next run.
330 */
331EOF
332        if($static) {
333                print OUT <<"EOF";
334${staticloader}void ERR_load_${lib}_strings(void);
335
336EOF
337        } else {
338                print OUT <<"EOF";
339${staticloader}void ERR_load_${lib}_strings(void);
340${staticloader}void ERR_unload_${lib}_strings(void);
341${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
342#define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
343
344EOF
345        }
346        print OUT <<"EOF";
347/* Error codes for the $lib functions. */
348
349/* Function codes. */
350EOF
351
352        foreach $i (@function) {
353                $z=6-int(length($i)/8);
354                if($fcodes{$i} eq "X") {
355                        $fcodes{$i} = ++$fmax{$lib};
356                        print STDERR "New Function code $i\n" if $debug;
357                }
358                printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z;
359        }
360
361        print OUT "\n/* Reason codes. */\n";
362
363        foreach $i (@reasons) {
364                $z=6-int(length($i)/8);
365                if($rcodes{$i} eq "X") {
366                        $rcodes{$i} = ++$rmax{$lib};
367                        print STDERR "New Reason code   $i\n" if $debug;
368                }
369                printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z;
370        }
371        print OUT <<"EOF";
372
373#ifdef  __cplusplus
374}
375#endif
376#endif
377EOF
378        close OUT;
379
380        # Rewrite the C source file containing the error details.
381
382        # First, read any existing reason string definitions:
383        my %err_reason_strings;
384        if (open(IN,"<$cfile")) {
385                while (<IN>) {
386                        if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
387                                $err_reason_strings{$1} = $2;
388                        }
389                }
390                close(IN);
391        }
392
393        my $hincf;
394        if($static) {
395                $hfile =~ /([^\/]+)$/;
396                $hincf = "<openssl/$1>";
397        } else {
398                $hincf = "\"$hfile\"";
399        }
400
401
402        open (OUT,">$cfile") || die "Can't open $cfile for writing";
403
404        print OUT <<"EOF";
405/* $cfile */
406/* ====================================================================
407 * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
408 *
409 * Redistribution and use in source and binary forms, with or without
410 * modification, are permitted provided that the following conditions
411 * are met:
412 *
413 * 1. Redistributions of source code must retain the above copyright
414 *    notice, this list of conditions and the following disclaimer.
415 *
416 * 2. Redistributions in binary form must reproduce the above copyright
417 *    notice, this list of conditions and the following disclaimer in
418 *    the documentation and/or other materials provided with the
419 *    distribution.
420 *
421 * 3. All advertising materials mentioning features or use of this
422 *    software must display the following acknowledgment:
423 *    "This product includes software developed by the OpenSSL Project
424 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
425 *
426 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
427 *    endorse or promote products derived from this software without
428 *    prior written permission. For written permission, please contact
429 *    openssl-core\@OpenSSL.org.
430 *
431 * 5. Products derived from this software may not be called "OpenSSL"
432 *    nor may "OpenSSL" appear in their names without prior written
433 *    permission of the OpenSSL Project.
434 *
435 * 6. Redistributions of any form whatsoever must retain the following
436 *    acknowledgment:
437 *    "This product includes software developed by the OpenSSL Project
438 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
439 *
440 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
441 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
442 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
444 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
445 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
446 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
447 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
448 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
449 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
450 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
451 * OF THE POSSIBILITY OF SUCH DAMAGE.
452 * ====================================================================
453 *
454 * This product includes cryptographic software written by Eric Young
455 * (eay\@cryptsoft.com).  This product includes software written by Tim
456 * Hudson (tjh\@cryptsoft.com).
457 *
458 */
459
460/* NOTE: this file was auto generated by the mkerr.pl script: any changes
461 * made to it will be overwritten when the script next updates this file,
462 * only reason strings will be preserved.
463 */
464
465#include <stdio.h>
466#include <openssl/err.h>
467#include $hincf
468
469/* BEGIN ERROR CODES */
470#ifndef OPENSSL_NO_ERR
471static ERR_STRING_DATA ${lib}_str_functs[]=
472        {
473EOF
474        # Add each function code: if a function name is found then use it.
475        foreach $i (@function) {
476                my $fn;
477                $i =~ /^${lib}_F_(\S+)$/;
478                $fn = $1;
479                if(exists $ftrans{$fn}) {
480                        $fn = $ftrans{$fn};
481                }
482                print OUT "{ERR_PACK(0,$i,0),\t\"$fn\"},\n";
483        }
484        print OUT <<"EOF";
485{0,NULL}
486        };
487
488static ERR_STRING_DATA ${lib}_str_reasons[]=
489        {
490EOF
491        # Add each reason code.
492        foreach $i (@reasons) {
493                my $rn;
494                my $nspc = 0;
495                if (exists $err_reason_strings{$i}) {
496                        $rn = $err_reason_strings{$i};
497                } else {
498                        $i =~ /^${lib}_R_(\S+)$/;
499                        $rn = $1;
500                        $rn =~ tr/_[A-Z]/ [a-z]/;
501                }
502                $nspc = 40 - length($i) unless length($i) > 40;
503                $nspc = " " x $nspc;
504                print OUT "{${i}${nspc},\"$rn\"},\n";
505        }
506if($static) {
507        print OUT <<"EOF";
508{0,NULL}
509        };
510
511#endif
512
513${staticloader}void ERR_load_${lib}_strings(void)
514        {
515        static int init=1;
516
517        if (init)
518                {
519                init=0;
520#ifndef OPENSSL_NO_ERR
521                ERR_load_strings(ERR_LIB_${lib},${lib}_str_functs);
522                ERR_load_strings(ERR_LIB_${lib},${lib}_str_reasons);
523#endif
524
525                }
526        }
527EOF
528} else {
529        print OUT <<"EOF";
530{0,NULL}
531        };
532
533#endif
534
535#ifdef ${lib}_LIB_NAME
536static ERR_STRING_DATA ${lib}_lib_name[]=
537        {
538{0      ,${lib}_LIB_NAME},
539{0,NULL}
540        };
541#endif
542
543
544static int ${lib}_lib_error_code=0;
545static int ${lib}_error_init=1;
546
547${staticloader}void ERR_load_${lib}_strings(void)
548        {
549        if (${lib}_lib_error_code == 0)
550                ${lib}_lib_error_code=ERR_get_next_error_library();
551
552        if (${lib}_error_init)
553                {
554                ${lib}_error_init=0;
555#ifndef OPENSSL_NO_ERR
556                ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs);
557                ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons);
558#endif
559
560#ifdef ${lib}_LIB_NAME
561                ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0);
562                ERR_load_strings(0,${lib}_lib_name);
563#endif
564                }
565        }
566
567${staticloader}void ERR_unload_${lib}_strings(void)
568        {
569        if (${lib}_error_init == 0)
570                {
571#ifndef OPENSSL_NO_ERR
572                ERR_unload_strings(${lib}_lib_error_code,${lib}_str_functs);
573                ERR_unload_strings(${lib}_lib_error_code,${lib}_str_reasons);
574#endif
575
576#ifdef ${lib}_LIB_NAME
577                ERR_unload_strings(0,${lib}_lib_name);
578#endif
579                ${lib}_error_init=1;
580                }
581        }
582
583${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
584        {
585        if (${lib}_lib_error_code == 0)
586                ${lib}_lib_error_code=ERR_get_next_error_library();
587        ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line);
588        }
589EOF
590
591}
592
593        close OUT;
594        undef %err_reason_strings;
595}
596
597if($debug && defined(%notrans)) {
598        print STDERR "The following function codes were not translated:\n";
599        foreach(sort keys %notrans)
600        {
601                print STDERR "$_\n";
602        }
603}
604
605# Make a list of unreferenced function and reason codes
606
607foreach (keys %fcodes) {
608        push (@funref, $_) unless exists $ufcodes{$_};
609}
610
611foreach (keys %rcodes) {
612        push (@runref, $_) unless exists $urcodes{$_};
613}
614
615if($debug && defined(@funref) ) {
616        print STDERR "The following function codes were not referenced:\n";
617        foreach(sort @funref)
618        {
619                print STDERR "$_\n";
620        }
621}
622
623if($debug && defined(@runref) ) {
624        print STDERR "The following reason codes were not referenced:\n";
625        foreach(sort @runref)
626        {
627                print STDERR "$_\n";
628        }
629}
Note: See TracBrowser for help on using the repository browser.