X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=util%2Fmkerr.pl;h=ba2fd6eba307d86b58a351bd5bfdd01ab95e369c;hp=bd4f85945fd2b3f199cf4467d78031f9b03e32e8;hb=cc0661374f032b788016300be8705feeca10a93a;hpb=a8e00b17ce840c58787e45411fa2ac4d6b1fb10c diff --git a/util/mkerr.pl b/util/mkerr.pl index bd4f85945f..ba2fd6eba3 100644 --- a/util/mkerr.pl +++ b/util/mkerr.pl @@ -1,6 +1,7 @@ #!/usr/local/bin/perl -w my $config = "crypto/err/openssl.ec"; +my $hprefix = "openssl/"; my $debug = 0; my $rebuild = 0; my $static = 1; @@ -9,11 +10,19 @@ my $reindex = 0; my $dowrite = 0; my $staticloader = ""; +my $pack_errcode; +my $load_errcode; + +my $errcount; + 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; shift @ARGV; @@ -35,6 +44,71 @@ while (@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] ... + +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
+ statements with prefix P. Default: 'openssl/' (without + the quotes, naturally) + + -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: + (, , , ) + 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__strings(void); + void ERR_unload__strings(void); + void ERR__error(int f, int r, char *fn, int ln); + #define err(f,r) ERR__error(f,r,__FILE__,__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. + + -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. + +EOF + exit 1; } else { last; } @@ -60,8 +134,10 @@ while() $cskip{$3} = $1; if($3 ne "NONE") { $csrc{$1} = $3; - $fmax{$1} = 99; - $rmax{$1} = 99; + $fmax{$1} = 100; + $rmax{$1} = 100; + $fassigned{$1} = ":"; + $rassigned{$1} = ":"; $fnew{$1} = 0; $rnew{$1} = 0; } @@ -100,15 +176,24 @@ while (($hdr, $lib) = each %libinc) next; } - $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration + if(/\/\*/) { + if (not /\*\//) { # multiline comment... + $line = $_; # ... just accumulate + next; + } else { + s/\/\*.*?\*\///gs; # wipe it + } + } + if ($cpp) { - $cpp = 0 if /^#.*endif/; + $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 comments s/{[^{}]*}//gs; # ignore {} blocks if (/\{|\/\*/) { # Add a } so editor works... @@ -121,31 +206,37 @@ while (($hdr, $lib) = each %libinc) 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; - next if(/typedef\W/); - if (/\(\*(\w*)\([^\)]+/) { - my $name = $1; - $name =~ tr/[a-z]/[A-Z]/; - $ftrans{$name} = $1; - } elsif (/\w+\W+(\w+)\W*\(\s*\)(\s*__attribute__\(.*\)\s*)?$/s){ - # K&R C - next ; - } elsif (/\w+\W+\w+\W*\(.*\)(\s*__attribute__\(.*\)\s*)?$/s) { - while (not /\(\)(\s*__attribute__\(.*\)\s*)?$/s) { - s/[^\(\)]*\)(\s*__attribute__\(.*\)\s*)?$/\)/s; - s/\([^\(\)]*\)\)(\s*__attribute__\(.*\)\s*)?$/\)/s; - } - s/\(void\)//; - /(\w+(\{[0-9]+\})?)\W*\(\)/s; - my $name = $1; + + # 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 (/=/ or /DECLARE_STACK/)) { + } elsif (/[\(\)]/ and not (/=/)) { print STDERR "Header $hdr: cannot parse: $_;\n"; } } @@ -158,7 +249,7 @@ while (($hdr, $lib) = each %libinc) # maximum code used. if ($gotfile) { - while() { + while() { if(/^\#define\s+(\S+)\s+(\S+)/) { $name = $1; $code = $2; @@ -169,18 +260,52 @@ while (($hdr, $lib) = each %libinc) } 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; } @@ -197,13 +322,15 @@ while (($hdr, $lib) = each %libinc) # so all those unreferenced can be printed out. -print STDERR "Files loaded: " if $debug; foreach $file (@source) { # Don't parse the error source file. next if exists $cskip{$file}; - print STDERR $file if $debug; + print STDERR "File loaded: ".$file."\r" if $debug; open(IN, "<$file") || die "Can't open source file $file\n"; while() { + # skip obsoleted source files entirely! + last if(/^#error\s+obsolete/); + if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) { next unless exists $csrc{$2}; next if($1 eq "BIO_F_BUFFER_CTX"); @@ -213,6 +340,7 @@ foreach $file (@source) { $fnew{$2}++; } $notrans{$1} = 1 unless exists $ftrans{$3}; + 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}; @@ -221,11 +349,12 @@ foreach $file (@source) { $rcodes{$1} = "X"; $rnew{$2}++; } + print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug; } } close IN; } -print STDERR "\n" if $debug; +print STDERR " \n" if $debug; # Now process each library in turn. @@ -262,7 +391,7 @@ foreach $lib (keys %csrc) } else { push @out, "/* ====================================================================\n", -" * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved.\n", +" * Copyright (c) 2001-2009 The OpenSSL Project. All rights reserved.\n", " *\n", " * Redistribution and use in source and binary forms, with or without\n", " * modification, are permitted provided that the following conditions\n", @@ -318,6 +447,10 @@ foreach $lib (keys %csrc) "#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"; @@ -352,7 +485,16 @@ EOF foreach $i (@function) { $z=6-int(length($i)/8); if($fcodes{$i} eq "X") { - $fcodes{$i} = ++$fmax{$lib}; + $fassigned{$lib} =~ m/^:([^:]*):/; + $findcode = $1; + if (!defined($findcode)) { + $findcode = $fmax{$lib}; + } + while ($fassigned{$lib} =~ m/:$findcode:/) { + $findcode++; + } + $fcodes{$i} = $findcode; + $fassigned{$lib} .= "$findcode:"; print STDERR "New Function code $i\n" if $debug; } printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z; @@ -363,7 +505,16 @@ EOF foreach $i (@reasons) { $z=6-int(length($i)/8); if($rcodes{$i} eq "X") { - $rcodes{$i} = ++$rmax{$lib}; + $rassigned{$lib} =~ m/^:([^:]*):/; + $findcode = $1; + if (!defined($findcode)) { + $findcode = $rmax{$lib}; + } + while ($rassigned{$lib} =~ m/:$findcode:/) { + $findcode++; + } + $rcodes{$i} = $findcode; + $rassigned{$lib} .= "$findcode:"; print STDERR "New Reason code $i\n" if $debug; } printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z; @@ -386,25 +537,46 @@ EOF if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) { $err_reason_strings{$1} = $2; } + if (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) { + if (!exists $ftrans{$1} && ($1 ne $2)) { + print STDERR "WARNING: Mismatched function string $2\n"; + $ftrans{$1} = $2; + } + } } close(IN); } + my $hincf; if($static) { $hfile =~ /([^\/]+)$/; - $hincf = ""; + $hincf = "<${hprefix}$1>"; } else { $hincf = "\"$hfile\""; } + # If static we know the error code at compile time so use it + # in error definitions. + + if ($static) + { + $pack_errcode = "ERR_LIB_${lib}"; + $load_errcode = "0"; + } + else + { + $pack_errcode = "0"; + $load_errcode = "ERR_LIB_${lib}"; + } + open (OUT,">$cfile") || die "Can't open $cfile for writing"; print OUT <<"EOF"; /* $cfile */ /* ==================================================================== - * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -468,6 +640,10 @@ EOF /* BEGIN ERROR CODES */ #ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0) +#define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason) + static ERR_STRING_DATA ${lib}_str_functs[]= { EOF @@ -479,7 +655,8 @@ EOF if(exists $ftrans{$fn}) { $fn = $ftrans{$fn}; } - print OUT "{ERR_PACK(0,$i,0),\t\"$fn\"},\n"; +# print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n"; + print OUT "{ERR_FUNC($i),\t\"$fn\"},\n"; } print OUT <<"EOF"; {0,NULL} @@ -491,6 +668,7 @@ EOF # Add each reason code. foreach $i (@reasons) { my $rn; + my $rstr = "ERR_REASON($i)"; my $nspc = 0; if (exists $err_reason_strings{$i}) { $rn = $err_reason_strings{$i}; @@ -499,9 +677,9 @@ EOF $rn = $1; $rn =~ tr/_[A-Z]/ [a-z]/; } - $nspc = 40 - length($i) unless length($i) > 40; + $nspc = 40 - length($rstr) unless length($rstr) > 40; $nspc = " " x $nspc; - print OUT "{${i}${nspc},\"$rn\"},\n"; + print OUT "{${rstr}${nspc},\"$rn\"},\n"; } if($static) { print OUT <<"EOF"; @@ -512,17 +690,14 @@ if($static) { ${staticloader}void ERR_load_${lib}_strings(void) { - static int init=1; - - if (init) - { - init=0; #ifndef OPENSSL_NO_ERR - ERR_load_strings(ERR_LIB_${lib},${lib}_str_functs); - ERR_load_strings(ERR_LIB_${lib},${lib}_str_reasons); -#endif + if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) + { + ERR_load_strings($load_errcode,${lib}_str_functs); + ERR_load_strings($load_errcode,${lib}_str_reasons); } +#endif } EOF } else { @@ -627,3 +802,9 @@ if($debug && defined(@runref) ) { print STDERR "$_\n"; } } + +if($errcount) { + print STDERR "There were errors, failing...\n\n"; + exit $errcount; +} +