summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorRich Salz <rsalz@openssl.org>2017-06-07 15:12:03 -0400
committerRich Salz <rsalz@openssl.org>2017-06-07 15:12:03 -0400
commit52df25cf2e656146cb3b206d8220124f0417d03f (patch)
treea0502334c45d96ad9ab32a855ee5bea28df2191d /util
parentbe606c013d31847718ceb5d97c567988a771c2e5 (diff)
make error tables const and separate header file
Run perltidy on util/mkerr Change some mkerr flags, write some doc comments Make generated tables "const" when genearting lib-internal ones. Add "state" file for mkerr Renerate error tables and headers Rationalize declaration of ERR_load_XXX_strings Fix out-of-tree build Add -static; sort flags/vars for options. Also tweak code output Moved engines/afalg to engines (from master) Use -static flag Standard engine #include's of errors Don't linewrap err string tables unless necessary Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3392)
Diffstat (limited to 'util')
-rw-r--r--util/libcrypto.num1
-rwxr-xr-xutil/mkdef.pl79
-rwxr-xr-x[-rw-r--r--]util/mkerr.pl1255
3 files changed, 614 insertions, 721 deletions
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 6bb9129fbf..b2e5f68570 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4296,3 +4296,4 @@ UI_method_get_data_duplicator 4238 1_1_1 EXIST::FUNCTION:UI
UI_method_set_data_duplicator 4239 1_1_1 EXIST::FUNCTION:UI
UI_dup_user_data 4240 1_1_1 EXIST::FUNCTION:UI
UI_method_get_data_destructor 4241 1_1_1 EXIST::FUNCTION:UI
+ERR_load_strings_const 4242 1_1_1 EXIST::FUNCTION:
diff --git a/util/mkdef.pl b/util/mkdef.pl
index c9fa98ef05..0fdf965f7e 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -48,6 +48,8 @@
use lib ".";
use configdata;
use File::Spec::Functions;
+use File::Basename;
+use if $^O ne "VMS", 'File::Glob' => qw/glob/;
my $debug=0;
@@ -223,74 +225,29 @@ $max_ssl = $max_num;
$max_crypto = $max_num;
my $ssl="include/openssl/ssl.h";
+$ssl.=" include/openssl/sslerr.h";
$ssl.=" include/openssl/tls1.h";
$ssl.=" include/openssl/srtp.h";
+# When scanning include/openssl, skip all SSL files and some internal ones.
+my %skipthese;
+foreach my $f ( split(/\s+/, $ssl) ) {
+ $skipthese{$f} = 1;
+}
+$skipthese{'include/openssl/conf_api.h'} = 1;
+$skipthese{'include/openssl/ebcdic.h'} = 1;
+$skipthese{'include/openssl/opensslconf.h'} = 1;
+
# We use headers found in include/openssl and include/internal only.
# The latter is needed so libssl.so/.dll/.exe can link properly.
-my $crypto ="include/openssl/crypto.h";
+my $crypto ="include/internal/dso.h";
$crypto.=" include/internal/o_dir.h";
$crypto.=" include/internal/o_str.h";
$crypto.=" include/internal/err.h";
-$crypto.=" include/openssl/des.h" ; # unless $no_des;
-$crypto.=" include/openssl/idea.h" ; # unless $no_idea;
-$crypto.=" include/openssl/rc4.h" ; # unless $no_rc4;
-$crypto.=" include/openssl/rc5.h" ; # unless $no_rc5;
-$crypto.=" include/openssl/rc2.h" ; # unless $no_rc2;
-$crypto.=" include/openssl/blowfish.h" ; # unless $no_bf;
-$crypto.=" include/openssl/cast.h" ; # unless $no_cast;
-$crypto.=" include/openssl/whrlpool.h" ;
-$crypto.=" include/openssl/md2.h" ; # unless $no_md2;
-$crypto.=" include/openssl/md4.h" ; # unless $no_md4;
-$crypto.=" include/openssl/md5.h" ; # unless $no_md5;
-$crypto.=" include/openssl/mdc2.h" ; # unless $no_mdc2;
-$crypto.=" include/openssl/sha.h" ; # unless $no_sha;
-$crypto.=" include/openssl/ripemd.h" ; # unless $no_ripemd;
-$crypto.=" include/openssl/aes.h" ; # unless $no_aes;
-$crypto.=" include/openssl/camellia.h" ; # unless $no_camellia;
-$crypto.=" include/openssl/seed.h"; # unless $no_seed;
-
-$crypto.=" include/openssl/bn.h";
-$crypto.=" include/openssl/rsa.h" ; # unless $no_rsa;
-$crypto.=" include/openssl/dsa.h" ; # unless $no_dsa;
-$crypto.=" include/openssl/dh.h" ; # unless $no_dh;
-$crypto.=" include/openssl/ec.h" ; # unless $no_ec;
-$crypto.=" include/openssl/hmac.h" ; # unless $no_hmac;
-$crypto.=" include/openssl/cmac.h" ;
-
-$crypto.=" include/openssl/engine.h"; # unless $no_engine;
-$crypto.=" include/openssl/stack.h" ; # unless $no_stack;
-$crypto.=" include/openssl/buffer.h" ; # unless $no_buffer;
-$crypto.=" include/openssl/bio.h" ; # unless $no_bio;
-$crypto.=" include/internal/dso.h" ; # unless $no_dso;
-$crypto.=" include/openssl/lhash.h" ; # unless $no_lhash;
-$crypto.=" include/openssl/conf.h";
-$crypto.=" include/openssl/txt_db.h";
-
-$crypto.=" include/openssl/evp.h" ; # unless $no_evp;
-$crypto.=" include/openssl/objects.h";
-$crypto.=" include/openssl/pem.h";
-#$crypto.=" include/openssl/meth.h";
-$crypto.=" include/openssl/asn1.h";
-$crypto.=" include/openssl/asn1t.h";
-$crypto.=" include/openssl/err.h" ; # unless $no_err;
-$crypto.=" include/openssl/pkcs7.h";
-$crypto.=" include/openssl/pkcs12.h";
-$crypto.=" include/openssl/x509.h";
-$crypto.=" include/openssl/x509_vfy.h";
-$crypto.=" include/openssl/x509v3.h";
-$crypto.=" include/openssl/ts.h";
-$crypto.=" include/openssl/rand.h";
-$crypto.=" include/openssl/comp.h" ; # unless $no_comp;
-$crypto.=" include/openssl/ocsp.h";
-$crypto.=" include/openssl/ui.h";
-#$crypto.=" include/openssl/store.h";
-$crypto.=" include/openssl/cms.h";
-$crypto.=" include/openssl/srp.h";
-$crypto.=" include/openssl/modes.h";
-$crypto.=" include/openssl/async.h";
-$crypto.=" include/openssl/ct.h";
-$crypto.=" include/openssl/kdf.h";
+foreach my $f ( glob(catfile($config{sourcedir},'include/openssl/*.h')) ) {
+ my $fn = "include/openssl/" . lc(basename($f));
+ $crypto .= " $fn" if !defined $skipthese{$fn} && $f !~ m@/[a-z]+err\.h$@;
+}
my $symhacks="include/openssl/symhacks.h";
@@ -380,7 +337,7 @@ sub do_defs
{
my $fn = catfile($config{sourcedir},$file);
print STDERR "DEBUG: starting on $fn:\n" if $debug;
- open(IN,"<$fn") || die "unable to open $fn:$!\n";
+ open(IN,"<$fn") || die "Can't open $fn, $!,";
my $line = "", my $def= "";
my %tag = (
(map { $_ => 0 } @known_platforms),
diff --git a/util/mkerr.pl b/util/mkerr.pl
index 4645658e99..23e4a22797 100644..100755
--- a/util/mkerr.pl
+++ b/util/mkerr.pl
@@ -6,585 +6,534 @@
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
-my $config = "crypto/err/openssl.ec";
-my $debug = 0;
-my $unref = 0;
-my $rebuild = 0;
-my $static = 1;
-my $recurse = 0;
-my $reindex = 0;
-my $dowrite = 0;
-my $staticloader = "";
-my @t = localtime();
-my $YEAR = @t[5] + 1900;
-
-my $pack_errcode;
-my $load_errcode;
-
-my $errcount;
-my $year = (localtime)[5] + 1900;
-
-while (@ARGV) {
- my $arg = $ARGV[0];
- if($arg eq "-conf") {
- shift @ARGV;
- $config = shift @ARGV;
- } elsif($arg eq "-hprefix") {
- shift @ARGV;
- $hprefix = shift @ARGV;
- } elsif($arg eq "-debug") {
- $debug = 1;
- $unref = 1;
- shift @ARGV;
- } elsif($arg eq "-rebuild") {
- $rebuild = 1;
- shift @ARGV;
- } elsif($arg eq "-recurse") {
- $recurse = 1;
- shift @ARGV;
- } elsif($arg eq "-reindex") {
- $reindex = 1;
- shift @ARGV;
- } elsif($arg eq "-nostatic") {
- $static = 0;
- shift @ARGV;
- } elsif($arg eq "-staticloader") {
- $staticloader = "static ";
- shift @ARGV;
- } elsif($arg eq "-unref") {
- $unref = 1;
- shift @ARGV;
- } elsif($arg eq "-write") {
- $dowrite = 1;
- shift @ARGV;
- } elsif($arg eq "-help" || $arg eq "-h" || $arg eq "-?" || $arg eq "--help") {
- print STDERR <<"EOF";
-mkerr.pl [options] ...
+use strict;
+use warnings;
+
+my $config = "crypto/err/openssl.ec";
+my $debug = 0;
+my $internal = 0;
+my $nowrite = 0;
+my $rebuild = 0;
+my $reindex = 0;
+my $static = 0;
+my $unref = 0;
+
+my $errors = 0;
+my @t = localtime();
+my $YEAR = $t[5] + 1900;
+
+sub phase
+{
+ my $text = uc(shift);
+ print STDERR "\n---\n$text\n" if $debug;
+}
+
+sub help
+{
+ print STDERR <<"EOF";
+mkerr.pl [options] [files...]
Options:
- -conf F Use the config file F instead of the default one:
- crypto/err/openssl.ec
-
- -hprefix P Prepend the filenames in generated #include <header>
- statements with prefix P. Default: 'openssl/' (without
- the quotes, naturally)
- NOTE: not used any more because our include directory
- structure has changed.
-
- -debug Turn on debugging verbose output on stderr.
-
- -rebuild Rebuild all header and C source files, irrespective of the
- fact if any error or function codes have been added/removed.
- Default: only update files for libraries which saw change
- (of course, this requires '-write' as well, or no
- files will be touched!)
-
- -recurse scan a preconfigured set of directories / files for error and
- function codes:
- (<crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <apps/*.c>)
- When this option is NOT specified, the filelist is taken from
- the commandline instead. Here, wildcards may be embedded. (Be
- sure to escape those to prevent the shell from expanding them
- for you when you wish mkerr.pl to do so instead.)
- Default: take file list to scan from the command line.
-
- -reindex Discard the numeric values previously assigned to the error
- and function codes as extracted from the scanned header files;
- instead renumber all of them starting from 100. (Note that
- the numbers assigned through 'R' records in the config file
- remain intact.)
- Default: keep previously assigned numbers. (You are warned
- when collisions are detected.)
-
- -nostatic Generates a different source code, where these additional
- functions are generated for each library specified in the
- config file:
- void ERR_load_<LIB>_strings(void);
- void ERR_unload_<LIB>_strings(void);
- void ERR_<LIB>_error(int f, int r, char *fn, int ln);
- #define <LIB>err(f,r) ERR_<LIB>_error(f,r,OPENSSL_FILE,OPENSSL_LINE)
- while the code facilitates the use of these in an environment
- where the error support routines are dynamically loaded at
- runtime.
- Default: 'static' code generation.
-
- -staticloader Prefix generated functions with the 'static' scope modifier.
- Default: don't write any scope modifier prefix.
-
- -unref Print out unreferenced function and reason codes.
-
- -write Actually (over)write the generated code to the header and C
- source files as assigned to each library through the config
- file.
- Default: don't write.
-
- -help / -h / -? / --help Show this help text.
-
- ... Additional arguments are added to the file list to scan,
- assuming '-recurse' was NOT specified on the command line.
+ -conf FILE Use the named config file FILE instead of the default.
+
+ -debug Verbose output debugging on stderr.
+
+ -internal Generate code that is to be built as part of OpenSSL itself.
+ Also scans internal list of files.
+
+ -nowrite Do not write the header/source files, even if changed.
+
+ -rebuild Rebuild all header and C source files, even if there
+ were no changes.
+
+ -reindex Ignore previously assigned values (except for R records in
+ the config file) and renumber everything starting at 100.
+
+ -static Make the load/unload functions static.
+
+ -unref List all unreferenced function and reason codes on stderr;
+ implies -nowrite.
+
+ -help Show this help text.
+
+ ... Additional arguments are added to the file list to scan,
+ if '-internal' was NOT specified on the command line.
EOF
- exit 1;
- } else {
- last;
- }
}
-if($recurse) {
- @source = ( <crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <ssl/*/*.c> )
-} else {
- @source = @ARGV;
+while ( @ARGV ) {
+ my $arg = $ARGV[0];
+ last unless $arg =~ /-.*/;
+ $arg = $1 if $arg =~ /-(-.*)/;
+ if ( $arg eq "-conf" ) {
+ $config = $ARGV[1];
+ shift @ARGV;
+ } elsif ( $arg eq "-debug" ) {
+ $debug = 1;
+ $unref = 1;
+ } elsif ( $arg eq "-internal" ) {
+ $internal = 1;
+ } elsif ( $arg eq "-nowrite" ) {
+ $nowrite = 1;
+ } elsif ( $arg eq "-rebuild" ) {
+ $rebuild = 1;
+ } elsif ( $arg eq "-reindex" ) {
+ $reindex = 1;
+ } elsif ( $arg eq "-static" ) {
+ $static = 1;
+ } elsif ( $arg eq "-unref" ) {
+ $unref = 1;
+ $nowrite = 1;
+ } elsif ( $arg =~ /-*h(elp)?/ ) {
+ &help();
+ exit;
+ } elsif ( $arg =~ /-.*/ ) {
+ die "Unknown option $arg; use -h for help.\n";
+ }
+ shift @ARGV;
}
-# Read in the config file
-
-open(IN, "<$config") || die "Can't open config file $config";
+my @source;
+if ( $internal ) {
+ die "Cannot mix -internal and -static\n" if $static;
+ die "Extra parameters given.\n" if @ARGV;
+ @source = ( glob('crypto/*.c'), glob('crypto/*/*.c'),
+ glob('ssl/*.c'), glob('ssl/*/*.c') );
+} else {
+ @source = @ARGV;
+}
-# Parse config file
+# Data parsed out of the config and state files.
+my %hinc; # lib -> header
+my %libinc; # header -> lib
+my %cskip; # error_file -> lib
+my %errorfile; # lib -> error file name
+my %fmax; # lib -> max assigned function code
+my %rmax; # lib -> max assigned reason code
+my %fassigned; # lib -> colon-separated list of assigned function codes
+my %rassigned; # lib -> colon-separated list of assigned reason codes
+my %fnew; # lib -> count of new function codes
+my %rnew; # lib -> count of new reason codes
+my %rextra; # "extra" reason code -> lib
+my %rcodes; # reason-name -> value
+my %ftrans; # old name -> #define-friendly name (all caps)
+my %fcodes; # function-name -> value
+my $statefile; # state file with assigned reason and function codes
+
+# Read and parse the config file
+open(IN, "$config") || die "Can't open config file $config, $!,";
+while ( <IN> ) {
+ next if /^#/ || /^$/;
+ if ( /^L\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
+ my $lib = $1;
+ my $hdr = $2;
+ my $err = $3;
+ $hinc{$lib} = $hdr;
+ $libinc{$hdr} = $lib;
+ $cskip{$err} = $lib;
+ next if $err eq 'NONE';
+ $errorfile{$lib} = $err;
+ $fmax{$lib} = 100;
+ $rmax{$lib} = 100;
+ $fassigned{$lib} = ":";
+ $rassigned{$lib} = ":";
+ $fnew{$lib} = 0;
+ $rnew{$lib} = 0;
+ } elsif ( /^R\s+(\S+)\s+(\S+)/ ) {
+ $rextra{$1} = $2;
+ $rcodes{$1} = $2;
+ } elsif ( /^S\s+(\S+)/ ) {
+ $statefile = $1;
+ } else {
+ die "Illegal config line $_\n";
+ }
+}
+close IN;
-while(<IN>)
-{
- if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
- $hinc{$1} = $2;
- $libinc{$2} = $1;
- $cskip{$3} = $1;
- if($3 ne "NONE") {
- $csrc{$1} = $3;
- $fmax{$1} = 100;
- $rmax{$1} = 100;
- $fassigned{$1} = ":";
- $rassigned{$1} = ":";
- $fnew{$1} = 0;
- $rnew{$1} = 0;
- }
- } elsif (/^F\s+(\S+)/) {
- # Add extra function with $1
- } elsif (/^R\s+(\S+)\s+(\S+)/) {
- $rextra{$1} = $2;
- $rcodes{$1} = $2;
- }
+if ( ! $statefile ) {
+ $statefile = $config;
+ $statefile =~ s/.ec/.txt/;
}
-close IN;
+# The statefile has all the previous assignments.
+&phase("Reading state");
+my $skippedstate = 0;
+if ( ! $reindex && $statefile ) {
+ open(STATE, "<$statefile") || die "Can't open $statefile, $!";
+
+ # Scan function and reason codes and store them: keep a note of the
+ # maximum code used.
+ while ( <STATE> ) {
+ next if /^#/ || /^$/;
+ die "Bad line in $statefile:\n$_\n" unless /(\S+)\s+(\d+)/;
+ my $name = $1;
+ my $code = $2;
+ my $lib = $name;
+ $lib =~ s/_.*//;
+ $lib = "SSL" if $lib =~ /TLS/;
+ if ( !defined $errorfile{$lib} ) {
+ print "Skipping $_";
+ $skippedstate++;
+ next;
+ }
+ if ( $name =~ /^[A-Z0-9]+_R_/ ) {
+ die "$lib reason code $code collision at $name\n"
+ if $rassigned{$lib} =~ /:$code:/;
+ $rassigned{$lib} .= "$code:";
+ if ( !exists $rextra{$name} ) {
+ $rmax{$lib} = $code if $code > $rmax{$lib};
+ }
+ $rcodes{$name} = $code;
+ } elsif ( $name =~ /^[A-Z0-9]+_F_/ ) {
+ die "$lib function code $code collision at $name\n"
+ if $fassigned{$lib} =~ /:$code:/;
+ $fassigned{$lib} .= "$code:";
+ $fmax{$lib} = $code if $code > $fmax{$lib};
+ $fcodes{$name} = $code;
+ } else {
+ die "Bad line in $statefile:\n$_\n";
+ }
+ }
+ close(STATE);
+
+ if ( $debug ) {
+ foreach my $lib ( sort keys %rmax ) {
+ print STDERR "Reason codes for ${lib}:\n";
+ if ( $rassigned{$lib} =~ m/^:(.*):$/ ) {
+ my @rassigned = sort { $a <=> $b } split( ":", $1 );
+ print STDERR " ", join(' ', @rassigned), "\n";
+ } else {
+ print STDERR " --none--\n";
+ }
+ }
+ print STDERR "\n";
+ foreach my $lib ( sort keys %fmax ) {
+ print STDERR "Function codes for ${lib}:\n";
+ if ( $fassigned{$lib} =~ m/^:(.*):$/ ) {
+ my @fassigned = sort { $a <=> $b } split( ":", $1 );
+ print STDERR " ", join(' ', @fassigned), "\n";
+ } else {
+ print STDERR " --none--\n";
+ }
+ }
+ }
+}
-# Scan each header file in turn and make a list of error codes
+# Scan each header file and make a list of error codes
# and function names
+&phase("Scanning headers");
+while ( ( my $hdr, my $lib ) = each %libinc ) {
+ next if $hdr eq "NONE";
+ print STDERR " ." if $debug;
+ my $line = "";
+ my $def = "";
+ my $linenr = 0;
+ my $cpp = 0;
+
+ open(IN, "<$hdr") || die "Can't open $hdr, $!,";
+ while ( <IN> ) {
+ $linenr++;
+
+ if ( $line ne '' ) {
+ $_ = $line . $_;
+ $line = '';
+ }
+
+ if ( /\\$/ ) {
+ $line = $_;
+ next;
+ }
+
+ if ( /\/\*/ ) {
+ if ( not /\*\// ) { # multiline comment...
+ $line = $_; # ... just accumulate
+ next;
+ } else {
+ s/\/\*.*?\*\///gs; # wipe it
+ }
+ }
-while (($hdr, $lib) = each %libinc)
-{
- next if($hdr eq "NONE");
- print STDERR "Scanning header file $hdr\n" if $debug;
- my $line = "", $def= "", $linenr = 0, $gotfile = 0, $cpp = 0;
- if (open(IN, "<$hdr")) {
- $gotfile = 1;
- while(<IN>) {
- $linenr++;
- print STDERR "line: $linenr\r" if $debug;
-
- last if(/BEGIN\s+ERROR\s+CODES/);
- if ($line ne '') {
- $_ = $line . $_;
- $line = '';
- }
-
- if (/\\$/) {
- $line = $_;
- next;
- }
-
- if(/\/\*/) {
- if (not /\*\//) { # multiline comment...
- $line = $_; # ... just accumulate
- next;
- } else {
- s/\/\*.*?\*\///gs; # wipe it
- }
- }
-
- if ($cpp) {
- $cpp++ if /^#\s*if/;
- $cpp-- if /^#\s*endif/;
- next;
- }
- $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration
-
- next if (/^\#/); # skip preprocessor directives
-
- s/{[^{}]*}//gs; # ignore {} blocks
-
- if (/\{|\/\*/) { # Add a } so editor works...
- $line = $_;
- } else {
- $def .= $_;
- }
- }
- }
-
- print STDERR " \r" if $debug;
- $defnr = 0;
- # Delete any DECLARE_ macros
- $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
- foreach (split /;/, $def) {
- $defnr++;
- print STDERR "def: $defnr\r" if $debug;
-
- # The goal is to collect function names from function declarations.
-
- s/^[\n\s]*//g;
- s/[\n\s]*$//g;
-
- # Skip over recognized non-function declarations
- next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
-
- # Remove STACK_OF(foo)
- s/STACK_OF\(\w+\)/void/;
-
- # Reduce argument lists to empty ()
- # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
- while(/\(.*\)/s) {
- s/\([^\(\)]+\)/\{\}/gs;
- s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
- }
- # pretend as we didn't use curly braces: {} -> ()
- s/\{\}/\(\)/gs;
-
- if (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
- my $name = $1; # a function name!
- $name =~ tr/[a-z]/[A-Z]/;
- $ftrans{$name} = $1;
- } elsif (/[\(\)]/ and not (/=/)) {
- print STDERR "Header $hdr: cannot parse: $_;\n";
- }
- }
-
- print STDERR " \r" if $debug;
-
- next if $reindex;
-
- # Scan function and reason codes and store them: keep a note of the
- # maximum code used.
-
- if ($gotfile) {
- while(<IN>) {
- if(/^\#\s*define\s+(\S+)\s+(\S+)/) {
- $name = $1;
- $code = $2;
- next if $name =~ /^${lib}err/;
- unless($name =~ /^${lib}_([RF])_(\w+)$/) {
- print STDERR "Invalid error code $name\n";
- next;
- }
- if($1 eq "R") {
- $rcodes{$name} = $code;
- if ($rassigned{$lib} =~ /:$code:/) {
- print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
- ++$errcount;
- }
- $rassigned{$lib} .= "$code:";
- if(!(exists $rextra{$name}) &&
- ($code > $rmax{$lib}) ) {
- $rmax{$lib} = $code;
- }
- } else {
- if ($fassigned{$lib} =~ /:$code:/) {
- print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
- ++$errcount;
- }
- $fassigned{$lib} .= "$code:";
- if($code > $fmax{$lib}) {
- $fmax{$lib} = $code;
- }
- $fcodes{$name} = $code;
- }
- }
- }
- }
-
- if ($debug) {
- if (defined($fmax{$lib})) {
- print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
- $fassigned{$lib} =~ m/^:(.*):$/;
- @fassigned = sort {$a <=> $b} split(":", $1);
- print STDERR " @fassigned\n";
- }
- if (defined($rmax{$lib})) {
- print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
- $rassigned{$lib} =~ m/^:(.*):$/;
- @rassigned = sort {$a <=> $b} split(":", $1);
- print STDERR " @rassigned\n";
- }
- }
-
- if ($lib eq "SSL") {
- if ($rmax{$lib} >= 1000) {
- print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
- print STDERR "!! Any new alerts must be added to $config.\n";
- ++$errcount;
- print STDERR "\n";
- }
- }
- close IN;
+ if ( $cpp ) {
+ $cpp++ if /^#\s*if/;
+ $cpp-- if /^#\s*endif/;
+ next;
+ }
+ $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration
+
+ next if /^\#/; # skip preprocessor directives
+
+ s/{[^{}]*}//gs; # ignore {} blocks
+
+ if ( /\{|\/\*/ ) { # Add a so editor works...
+ $line = $_;
+ } else {
+ $def .= $_;
+ }
+ }
+
+ # Delete any DECLARE_ macros
+ my $defnr = 0;
+ $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
+ foreach ( split /;/, $def ) {
+ $defnr++;
+ # The goal is to collect function names from function declarations.
+
+ s/^[\n\s]*//g;
+ s/[\n\s]*$//g;
+
+ # Skip over recognized non-function declarations
+ next if /typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/;
+
+ # Remove STACK_OF(foo)
+ s/STACK_OF\(\w+\)/void/;
+
+ # Reduce argument lists to empty ()
+ # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
+ while ( /\(.*\)/s ) {
+ s/\([^\(\)]+\)/\{\}/gs;
+ s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
+ }
+
+ # pretend as we didn't use curly braces: {} -> ()
+ s/\{\}/\(\)/gs;
+
+ if ( /(\w+)\s*\(\).*/s ) { # first token prior [first] () is
+ my $name = $1; # a function name!
+ $name =~ tr/[a-z]/[A-Z]/;
+ $ftrans{$name} = $1;
+ } elsif ( /[\(\)]/ and not(/=/) ) {
+ print STDERR "Header $hdr: cannot parse: $_;\n";
+ }
+ }
+
+ next if $reindex;
+
+ if ( $lib eq "SSL" && $rmax{$lib} >= 1000 ) {
+ print STDERR "SSL error codes 1000+ are reserved for alerts.\n";
+ print STDERR "Any new alerts must be added to $config.\n";
+ $errors++;
+ }
+ close IN;
}
+print STDERR "\n" if $debug;
# Scan each C source file and look for function and reason codes
# This is done by looking for strings that "look like" function or
# reason codes: basically anything consisting of all upper case and
# numerics which has _F_ or _R_ in it and which has the name of an
-# error library at the start. This seems to work fine except for the
+# error library at the start. This seems to work fine except for the
# oddly named structure BIO_F_CTX which needs to be ignored.
# If a code doesn't exist in list compiled from headers then mark it
# with the value "X" as a place holder to give it a value later.
-# Store all function and reason codes found in %ufcodes and %urcodes
+# Store all function and reason codes found in %usedfuncs and %usedreasons
# so all those unreferenced can be printed out.
-
-
-foreach $file (@source) {
- # Don't parse the error source file.
- next if exists $cskip{$file};
- print STDERR "File loaded: ".$file."\r" if $debug;
- open(IN, "<$file") || die "Can't open source file $file\n";
- my $func;
- my $linenr = 0;
- while(<IN>) {
- # skip obsoleted source files entirely!
- last if(/^#error\s+obsolete/);
- $linenr++;
- if (!/;$/ && /^\**([a-zA-Z_].*[\s*])?([A-Za-z_0-9]+)\(.*([),]|$)/)
- {
- /^([^()]*(\([^()]*\)[^()]*)*)\(/;
- $1 =~ /([A-Za-z_0-9]*)$/;
- $func = $1;
- }
-
- if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
- next unless exists $csrc{$2};
- next if($1 eq "BIO_F_BUFFER_CTX");
- $ufcodes{$1} = 1;
- if(!exists $fcodes{$1}) {
- $fcodes{$1} = "X";
- $fnew{$2}++;
- }
- $ftrans{$3} = $func unless exists $ftrans{$3};
- if (uc $func ne $3) {
+&phase("Scanning source");
+my %usedfuncs;
+my %usedreasons;
+foreach my $file ( @source ) {
+ # Don't parse the error source file.
+ next if exists $cskip{$file};
+ open( IN, "<$file" ) || die "Can't open $file, $!,";
+ my $func;
+ my $linenr = 0;
+ print STDERR "$file:\n" if $debug;
+ while ( <IN> ) {
+
+ # skip obsoleted source files entirely!
+ last if /^#error\s+obsolete/;
+ $linenr++;
+ if ( !/;$/ && /^\**([a-zA-Z_].*[\s*])?([A-Za-z_0-9]+)\(.*([),]|$)/ ) {
+ /^([^()]*(\([^()]*\)[^()]*)*)\(/;
+ $1 =~ /([A-Za-z_0-9]*)$/;
+ $func = $1;
+ }
+
+ if ( /(([A-Z0-9]+)_F_([A-Z0-9_]+))/ ) {
+ next unless exists $errorfile{$2};
+ next if $1 eq "BIO_F_BUFFER_CTX";
+ $usedfuncs{$1} = 1;
+ if ( !exists $fcodes{$1} ) {
+ print STDERR " New function $1\n" if $debug;
+ $fcodes{$1} = "X";
+ $fnew{$2}++;
+ }
+ $ftrans{$3} = $func unless exists $ftrans{$3};
+ if ( uc($func) ne $3 ) {
print STDERR "ERROR: mismatch $file:$linenr $func:$3\n";
- $errcount++;
+ $errors++;
+ }
+ print STDERR " Function $1 = $fcodes{$1}\n"
+ if $debug;
+ }
+ if ( /(([A-Z0-9]+)_R_[A-Z0-9_]+)/ ) {
+ next unless exists $errorfile{$2};
+ $usedreasons{$1} = 1;
+ if ( !exists $rcodes{$1} ) {
+ print STDERR " New reason $1\n" if $debug;
+ $rcodes{$1} = "X";
+ $rnew{$2}++;
}
- print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug;
- }
- if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
- next unless exists $csrc{$2};
- $urcodes{$1} = 1;
- if(!exists $rcodes{$1}) {
- $rcodes{$1} = "X";
- $rnew{$2}++;
- }
- print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug;
- }
- }
- close IN;
+ print STDERR " Reason $1 = $rcodes{$1}\n" if $debug;
+ }
+ }
+ close IN;
}
-print STDERR " \n" if $debug;
+print STDERR "\n" if $debug;
# Now process each library in turn.
+&phase("Writing files");
+my $newstate = 0;
+foreach my $lib ( keys %errorfile ) {
+ if ( ! $fnew{$lib} && ! $rnew{$lib} ) {
+ next unless $rebuild;
+ }
+ next if $nowrite;
+ print STDERR "$lib: $fnew{$lib} new functions\n" if $fnew{$lib};
+ print STDERR "$lib: $rnew{$lib} new reasons\n" if $rnew{$lib};
+ $newstate = 1;
-foreach $lib (keys %csrc)
-{
- my $hfile = $hinc{$lib};
- my $cfile = $csrc{$lib};
- if(!$fnew{$lib} && !$rnew{$lib}) {
- next unless $rebuild;
- } else {
- print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
- print STDERR " $rnew{$lib} New Reasons.\n";
- next unless $dowrite;
- }
-
- # If we get here then we have some new error codes so we
- # need to rebuild the header file and C file.
-
- # Make a sorted list of error and reason codes for later use.
-
- my @function = sort grep(/^${lib}_/,keys %fcodes);
- my @reasons = sort grep(/^${lib}_/,keys %rcodes);
-
- # Rewrite the header file
-
- $cpp = 0;
- $cplusplus = 0;
- if (open(IN, "<$hfile")) {
- # Copy across the old file
- while(<IN>) {
- $cplusplus = $cpp if /^#.*ifdef.*cplusplus/;
- $cpp++ if /^#\s*if/;
- $cpp-- if /^#\s*endif/;
- push @out, $_;
- last if (/BEGIN ERROR CODES/);
- }
- close IN;
- } else {
- $cpp = 1;
- $cplusplus = 1;
- push @out,
-"/*\n",
-" * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved.\n",
-" *\n",
-" * Licensed under the OpenSSL license (the \"License\"). You may not use\n",
-" * this file except in compliance with the License. You can obtain a copy\n",
-" * in the file LICENSE in the source distribution or at\n",
-" * https://www.openssl.org/source/license.html\n",
-" */\n",
-"\n",
-"#ifndef HEADER_${lib}_ERR_H\n",
-"# define HEADER_${lib}_ERR_H\n",
-"\n",
-"# ifdef __cplusplus\n",
-"extern \"C\" {\n",
-"# endif\n",
-"\n",
-"/* BEGIN ERROR CODES */\n";
- }
- open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
-
- print OUT @out;
- undef @out;
- print OUT <<"EOF";
+ # If we get here then we have some new error codes so we
+ # need to rebuild the header file and C file.
+
+ # Make a sorted list of error and reason codes for later use.
+ my @function = sort grep( /^${lib}_/, keys %fcodes );
+ my @reasons = sort grep( /^${lib}_/, keys %rcodes );
+
+ # Rewrite the header file
+
+ my $hfile = $hinc{$lib};
+ $hfile =~ s/.h$/err.h/ if $internal;
+ open( OUT, ">$hfile" ) || die "Can't write to $hfile, $!,";
+ print OUT <<"EOF";
/*
- * The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the \"License\"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
*/
-EOF
- if($static) {
- print OUT <<"EOF";
-${staticloader}int ERR_load_${lib}_strings(void);
+#ifndef HEADER_${lib}ERR_H
+# define HEADER_${lib}ERR_H
EOF
- } else {
- print OUT <<"EOF";
-${staticloader}int ERR_load_${lib}_strings(void);
-${staticloader}void ERR_unload_${lib}_strings(void);
-${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
-# define ${lib}err(f,r) ERR_${lib}_error((f),(r),OPENSSL_FILE,OPENSSL_LINE)
-
+ if ( $internal ) {
+ # Declare the load function because the generate C file
+ # includes "fooerr.h" not "foo.h"
+ print OUT <<"EOF";
+# ifdef __cplusplus
+extern \"C\" {
+# endif
+int ERR_load_${lib}_strings(void);
+# ifdef __cplusplus
+}
+# endif
EOF
- }
- print OUT <<"EOF";
-/* Error codes for the $lib functions. */
+ } else {
+ print OUT <<"EOF";
+# define ${lib}err(f, r) ERR_${lib}_error((f), (r), OPENSSL_FILE, OPENSSL_LINE)
-/* Function codes. */
EOF
+ if ( ! $static ) {
+ print OUT <<"EOF";
+
+# ifdef __cplusplus
+extern \"C\" {
+# endif
+int ERR_load_${lib}_strings(void);
+void ERR_unload_${lib}_strings(void);
+void ERR_${lib}_error(int function, int reason, char *file, int line);
+# ifdef __cplusplus
+}
+# endif
+EOF
+ }
+ }
+
+ print OUT "\n/*\n * $lib function codes.\n */\n";
+ foreach my $i ( @function ) {
+ my $z = 48 - length($i);
+ if ( $fcodes{$i} eq "X" ) {
+ $fassigned{$lib} =~ m/^:([^:]*):/;
+ my $findcode = $1;
+ $findcode = $fmax{$lib} if !defined $findcode;
+ while ( $fassigned{$lib} =~ m/:$findcode:/ ) {
+ $findcode++;
+ }
+ $fcodes{$i} = $findcode;
+ $fassigned{$lib} .= "$findcode:";
+