New err_code.pl script to retain old error codes. This should allow the use
[openssl.git] / crypto / err / err_code.pl
1 #!/usr/local/bin/perl -w
2
3 # Modified by Steve Henson. It should now read in the .err
4 # file and only add new error codes, retaining the old
5 # numbers. 
6
7 # Before it re-sorted new codes and re-ordered the whole thing. 
8 # This is the motivation for the change: the re numbering caused large
9 # patch files even if only one error or reason code was added.
10 # To force regeneration of all error codes (the old behaviour) use the
11 # -regen flag.
12
13 $regen = 0;
14
15 while (@ARGV)
16         {
17         $in=shift(@ARGV);
18         if ($in =~ /^-conf$/)
19                 {
20                 $in=shift(@ARGV);
21                 open(IN,"<$in") || die "unable to open '$in'\n";
22                 while (<IN>)
23                         {
24                         s/#.*$//;
25                         s/\s+$//;
26                         next if (/^$/);
27                         if (/^L\s+(\S+)\s+(\S+)$/)
28                                 { $errfile{$1}=$2; }
29                         elsif (/^F\s+(\S+)$/)
30                                 { $function{$1}=1; }
31                         elsif (/^R\s+(\S+)\s+(\S+)$/)
32                                 { $r_value{$1}=$2; }
33                         else { die "bad input line: $in:$.\n"; }
34                         }
35                 close(IN);
36                 next;
37                 }
38         elsif ($in =~ /^-regen/)
39                 {
40                 $regen = 1;
41                 next;
42         }
43
44         open(IN,"<$in") || die "unable to open '$in'\n";
45         $last="";
46         while (<IN>)
47                 {
48                 if (/err\(([A-Z0-9]+_F_[0-9A-Z_]+)\s*,\s*([0-9A-Z]+_R_[0-9A-Z_]+)\s*\)/)
49                         {
50 # Not sure what this was supposed to be for: it's broken anyway [steve]
51 #                       if ($1 != $last)
52 #                               {
53 #                               if ($function{$1} == 0)
54 #                                       {
55 #                                       printf STDERR "$. $1 is bad\n";
56 #                                       }
57 #                               }
58                         $function{$1}++;
59                         $last=$1;
60                         $reason{$2}++;
61                         }
62                 }
63         close(IN);
64         }
65
66 foreach (keys %function,keys %reason)
67         {
68         /^([A-Z0-9]+)_/;
69         $prefix{$1}++;
70         }
71
72 @F=sort keys %function;
73 @R=sort keys %reason;
74 foreach $j (sort keys %prefix)
75         {
76         next if !defined $errfile{$j};
77         next if $errfile{$j} eq "NONE";
78         printf STDERR "doing %-6s - ",$j;
79         @f=grep(/^${j}_/,@F);
80         @r=grep(/^${j}_/,@R);
81         if (defined($errfile{$j}))
82                 {
83                 read_errcodes($errfile{$j});
84                 # Check to see if any new codes: if not ignore.
85                 $new_codes = 0;
86                 foreach (@f) {
87                         if(!exists $func_codes{$_}) {
88                                 $new_codes = 1;
89                                 last;
90                         }
91                 }
92                 if(!$new_codes) {
93                         foreach (@r) {
94                                 if(!exists $reason_codes{$_}) {
95                                         $new_codes = 1;
96                                         last;
97                                 }
98                         }
99                 }
100                 if(!$new_codes) {
101                         print STDERR "No New Codes\n";
102                         next;
103                 }
104                 open(OUT,">$errfile{$j}") ||
105                         die "unable to open '$errfile{$j}':$!\n";
106                 $close_file=1;
107                 }
108         else
109                 {
110                 $min_func = 100;
111                 $min_reason = 100;
112                 *OUT=*STDOUT;
113                 $close_file=0;
114                 }
115         $num=$min_func;
116         print OUT "/* Error codes for the $j functions. */\n\n";
117         print OUT "/* Function codes. */\n";
118         $f_count=0;
119         foreach $i (@f)
120                 {
121                 $z=6-int(length($i)/8);
122                 if(exists $func_codes{$i}) {
123                         printf OUT "#define $i%s $func_codes{$i}\n","\t" x $z;
124                 } else {
125                         printf OUT "#define $i%s $num\n","\t" x $z;
126                         $num++;
127                 }
128                 $f_count++;
129                 }
130         $num=$min_reason;
131         print OUT "\n/* Reason codes. */\n";
132         $r_count=0;
133         foreach $i (@r)
134                 {
135                 $z=6-int(length($i)/8);
136                 if (exists $reason_codes{$i}) {
137                         printf OUT "#define $i%s $reason_codes{$i}\n","\t" x $z;
138                 } elsif (exists $r_value{$i}) {
139                         printf OUT "#define $i%s $r_value{$i}\n","\t" x $z;
140                 } else {
141                         printf OUT "#define $i%s $num\n","\t" x $z;
142                         $num++;
143                 }
144                 $r_count++;
145                 }
146         close(OUT) if $close_file;
147
148         printf STDERR "%3d functions, %3d reasons\n",$f_count,$r_count;
149         }
150
151 # Read in the error codes and populate %function and %reason with the
152 # old codes. Also define $min_func and $min_reason with the smallest
153 # unused function and reason codes. Care is needed because the
154 # config file can define larger reason codes and these should be
155 # ignored.
156
157 sub read_errcodes {
158 $file = $_[0];
159 $min_func = 100;
160 $min_reason = 100;
161 undef %func_codes;
162 undef %reason_codes;
163 return if ($regen);
164 if (open IN, $file) {
165         while(<IN>) {
166                 if(/^#define\s*(\S*)\s*(\S*)/) {
167                         if (exists $function{$1} ) {
168                                 if($2 >= $min_func) {$min_func = $2 + 1;}
169                                 $func_codes{$1} = $2;
170                         } elsif ((defined %reason) && exists $reason{$1}) {
171                                 $reason_codes{$1} = $2;
172                                 if( !(exists $r_value{$1})  &&
173                                                  ($2 >= $min_reason))
174                                                          {$min_reason = $2 + 1;}
175                         }
176                 }
177         }
178         close IN;
179 }
180 }