2016-04-20 02:10:43 +00:00
|
|
|
#! /usr/bin/env perl
|
|
|
|
# Copyright 1999-2016 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
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
my $config = "crypto/err/openssl.ec";
|
|
|
|
my $debug = 0;
|
2015-12-22 19:20:11 +00:00
|
|
|
my $unref = 0;
|
1999-04-24 00:15:18 +00:00
|
|
|
my $rebuild = 0;
|
1999-04-24 17:28:43 +00:00
|
|
|
my $static = 1;
|
1999-04-24 00:15:18 +00:00
|
|
|
my $recurse = 0;
|
|
|
|
my $reindex = 0;
|
1999-04-24 17:28:43 +00:00
|
|
|
my $dowrite = 0;
|
2001-11-15 16:52:10 +00:00
|
|
|
my $staticloader = "";
|
2016-05-01 12:47:43 +00:00
|
|
|
my @t = localtime();
|
|
|
|
my $YEAR = @t[5] + 1900;
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2005-04-12 13:31:14 +00:00
|
|
|
my $pack_errcode;
|
|
|
|
my $load_errcode;
|
|
|
|
|
2007-04-05 17:03:09 +00:00
|
|
|
my $errcount;
|
2012-10-22 13:02:42 +00:00
|
|
|
my $year = (localtime)[5] + 1900;
|
2007-04-05 17:03:09 +00:00
|
|
|
|
1999-04-24 00:15:18 +00:00
|
|
|
while (@ARGV) {
|
|
|
|
my $arg = $ARGV[0];
|
|
|
|
if($arg eq "-conf") {
|
|
|
|
shift @ARGV;
|
|
|
|
$config = shift @ARGV;
|
2006-02-12 23:11:56 +00:00
|
|
|
} elsif($arg eq "-hprefix") {
|
|
|
|
shift @ARGV;
|
|
|
|
$hprefix = shift @ARGV;
|
1999-04-24 00:15:18 +00:00
|
|
|
} elsif($arg eq "-debug") {
|
|
|
|
$debug = 1;
|
2015-12-22 19:20:11 +00:00
|
|
|
$unref = 1;
|
1999-04-24 00:15:18 +00:00
|
|
|
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;
|
1999-04-24 17:28:43 +00:00
|
|
|
} elsif($arg eq "-nostatic") {
|
|
|
|
$static = 0;
|
|
|
|
shift @ARGV;
|
2001-11-15 16:52:10 +00:00
|
|
|
} elsif($arg eq "-staticloader") {
|
|
|
|
$staticloader = "static ";
|
|
|
|
shift @ARGV;
|
2015-12-22 19:20:11 +00:00
|
|
|
} elsif($arg eq "-unref") {
|
|
|
|
$unref = 1;
|
|
|
|
shift @ARGV;
|
1999-04-24 17:28:43 +00:00
|
|
|
} elsif($arg eq "-write") {
|
|
|
|
$dowrite = 1;
|
1999-04-24 00:15:18 +00:00
|
|
|
shift @ARGV;
|
2009-04-15 15:27:03 +00:00
|
|
|
} 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 <header>
|
|
|
|
statements with prefix P. Default: 'openssl/' (without
|
|
|
|
the quotes, naturally)
|
2016-05-18 17:52:34 +00:00
|
|
|
NOTE: not used any more because our include directory
|
|
|
|
structure has changed.
|
2009-04-15 15:27:03 +00:00
|
|
|
|
|
|
|
-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);
|
2016-02-17 22:04:47 +00:00
|
|
|
#define <LIB>err(f,r) ERR_<LIB>_error(f,r,OPENSSL_FILE,OPENSSL_LINE)
|
2009-04-15 15:27:03 +00:00
|
|
|
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.
|
|
|
|
|
2015-12-22 19:20:11 +00:00
|
|
|
-unref Print out unreferenced function and reason codes.
|
|
|
|
|
2009-04-15 15:27:03 +00:00
|
|
|
-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;
|
1999-04-24 00:15:18 +00:00
|
|
|
} else {
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if($recurse) {
|
2015-12-22 16:52:27 +00:00
|
|
|
@source = ( <crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>, <ssl/*/*.c> )
|
1999-04-24 00:15:18 +00:00
|
|
|
} else {
|
|
|
|
@source = @ARGV;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Read in the config file
|
|
|
|
|
|
|
|
open(IN, "<$config") || die "Can't open config file $config";
|
|
|
|
|
|
|
|
# Parse config file
|
|
|
|
|
|
|
|
while(<IN>)
|
|
|
|
{
|
|
|
|
if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
|
|
|
|
$hinc{$1} = $2;
|
2001-05-10 00:07:45 +00:00
|
|
|
$libinc{$2} = $1;
|
1999-04-24 00:15:18 +00:00
|
|
|
$cskip{$3} = $1;
|
|
|
|
if($3 ne "NONE") {
|
|
|
|
$csrc{$1} = $3;
|
2009-04-15 15:27:03 +00:00
|
|
|
$fmax{$1} = 100;
|
|
|
|
$rmax{$1} = 100;
|
2006-01-08 21:43:36 +00:00
|
|
|
$fassigned{$1} = ":";
|
|
|
|
$rassigned{$1} = ":";
|
1999-04-24 00:15:18 +00:00
|
|
|
$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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close IN;
|
|
|
|
|
|
|
|
# Scan each header file in turn and make a list of error codes
|
|
|
|
# and function names
|
|
|
|
|
2001-05-10 00:07:45 +00:00
|
|
|
while (($hdr, $lib) = each %libinc)
|
1999-04-24 00:15:18 +00:00
|
|
|
{
|
|
|
|
next if($hdr eq "NONE");
|
2016-05-18 17:52:34 +00:00
|
|
|
print STDERR "Scanning header file $hdr\n" if $debug;
|
|
|
|
my $line = "", $def= "", $linenr = 0, $gotfile = 0, $cpp = 0;
|
2002-02-07 19:23:35 +00:00
|
|
|
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 = '';
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2002-02-07 19:23:35 +00:00
|
|
|
if (/\\$/) {
|
|
|
|
$line = $_;
|
|
|
|
next;
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2006-01-01 18:42:05 +00:00
|
|
|
if(/\/\*/) {
|
|
|
|
if (not /\*\//) { # multiline comment...
|
|
|
|
$line = $_; # ... just accumulate
|
|
|
|
next;
|
|
|
|
} else {
|
|
|
|
s/\/\*.*?\*\///gs; # wipe it
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-07 19:23:35 +00:00
|
|
|
if ($cpp) {
|
2006-01-01 18:42:05 +00:00
|
|
|
$cpp++ if /^#\s*if/;
|
|
|
|
$cpp-- if /^#\s*endif/;
|
2002-02-07 19:23:35 +00:00
|
|
|
next;
|
|
|
|
}
|
2006-01-01 18:42:05 +00:00
|
|
|
$cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2002-02-07 19:23:35 +00:00
|
|
|
next if (/^\#/); # skip preprocessor directives
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2002-02-07 19:23:35 +00:00
|
|
|
s/{[^{}]*}//gs; # ignore {} blocks
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2002-02-07 19:23:35 +00:00
|
|
|
if (/\{|\/\*/) { # Add a } so editor works...
|
|
|
|
$line = $_;
|
|
|
|
} else {
|
|
|
|
$def .= $_;
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-07-24 07:01:57 +00:00
|
|
|
print STDERR " \r" if $debug;
|
|
|
|
$defnr = 0;
|
2006-11-21 21:29:44 +00:00
|
|
|
# Delete any DECLARE_ macros
|
|
|
|
$def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
|
1999-04-24 00:15:18 +00:00
|
|
|
foreach (split /;/, $def) {
|
2000-07-24 07:01:57 +00:00
|
|
|
$defnr++;
|
|
|
|
print STDERR "def: $defnr\r" if $debug;
|
|
|
|
|
2006-01-01 18:42:05 +00:00
|
|
|
# The goal is to collect function names from function declarations.
|
|
|
|
|
1999-04-24 11:23:20 +00:00
|
|
|
s/^[\n\s]*//g;
|
1999-04-24 00:15:18 +00:00
|
|
|
s/[\n\s]*$//g;
|
2006-01-01 18:42:05 +00:00
|
|
|
|
|
|
|
# Skip over recognized non-function declarations
|
2006-01-02 12:13:07 +00:00
|
|
|
next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
|
2006-01-01 18:42:05 +00:00
|
|
|
|
2006-11-21 21:29:44 +00:00
|
|
|
# Remove STACK_OF(foo)
|
|
|
|
s/STACK_OF\(\w+\)/void/;
|
|
|
|
|
2006-01-01 18:42:05 +00:00
|
|
|
# Reduce argument lists to empty ()
|
|
|
|
# fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
|
2006-01-02 12:13:07 +00:00
|
|
|
while(/\(.*\)/s) {
|
|
|
|
s/\([^\(\)]+\)/\{\}/gs;
|
|
|
|
s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
|
|
|
|
}
|
2006-01-01 18:42:05 +00:00
|
|
|
# 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!
|
1999-04-24 00:15:18 +00:00
|
|
|
$name =~ tr/[a-z]/[A-Z]/;
|
|
|
|
$ftrans{$name} = $1;
|
2006-01-01 18:42:05 +00:00
|
|
|
} elsif (/[\(\)]/ and not (/=/)) {
|
1999-04-24 00:15:18 +00:00
|
|
|
print STDERR "Header $hdr: cannot parse: $_;\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-07-24 07:01:57 +00:00
|
|
|
print STDERR " \r" if $debug;
|
|
|
|
|
1999-04-24 00:15:18 +00:00
|
|
|
next if $reindex;
|
|
|
|
|
|
|
|
# Scan function and reason codes and store them: keep a note of the
|
|
|
|
# maximum code used.
|
|
|
|
|
2002-02-07 19:23:35 +00:00
|
|
|
if ($gotfile) {
|
2006-01-08 21:43:36 +00:00
|
|
|
while(<IN>) {
|
2015-01-14 21:26:14 +00:00
|
|
|
if(/^\#\s*define\s+(\S+)\s+(\S+)/) {
|
1999-04-24 00:15:18 +00:00
|
|
|
$name = $1;
|
|
|
|
$code = $2;
|
2001-11-15 16:52:10 +00:00
|
|
|
next if $name =~ /^${lib}err/;
|
1999-04-24 00:15:18 +00:00
|
|
|
unless($name =~ /^${lib}_([RF])_(\w+)$/) {
|
|
|
|
print STDERR "Invalid error code $name\n";
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
if($1 eq "R") {
|
|
|
|
$rcodes{$name} = $code;
|
2006-01-08 21:43:36 +00:00
|
|
|
if ($rassigned{$lib} =~ /:$code:/) {
|
2009-04-15 15:27:03 +00:00
|
|
|
print STDERR "!! ERROR: $lib reason code $code assigned twice (collision at $name)\n";
|
2007-04-05 17:03:09 +00:00
|
|
|
++$errcount;
|
2006-01-08 21:43:36 +00:00
|
|
|
}
|
|
|
|
$rassigned{$lib} .= "$code:";
|
1999-04-24 00:15:18 +00:00
|
|
|
if(!(exists $rextra{$name}) &&
|
|
|
|
($code > $rmax{$lib}) ) {
|
|
|
|
$rmax{$lib} = $code;
|
|
|
|
}
|
|
|
|
} else {
|
2006-01-08 21:43:36 +00:00
|
|
|
if ($fassigned{$lib} =~ /:$code:/) {
|
2009-04-15 15:27:03 +00:00
|
|
|
print STDERR "!! ERROR: $lib function code $code assigned twice (collision at $name)\n";
|
2007-04-05 17:03:09 +00:00
|
|
|
++$errcount;
|
2006-01-08 21:43:36 +00:00
|
|
|
}
|
|
|
|
$fassigned{$lib} .= "$code:";
|
1999-04-24 00:15:18 +00:00
|
|
|
if($code > $fmax{$lib}) {
|
|
|
|
$fmax{$lib} = $code;
|
|
|
|
}
|
|
|
|
$fcodes{$name} = $code;
|
|
|
|
}
|
|
|
|
}
|
2006-01-08 21:43:36 +00:00
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
2006-01-08 19:54:32 +00:00
|
|
|
|
|
|
|
if ($debug) {
|
|
|
|
if (defined($fmax{$lib})) {
|
|
|
|
print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
|
2006-01-08 21:43:36 +00:00
|
|
|
$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";
|
2006-01-08 19:54:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-08 20:03:08 +00:00
|
|
|
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";
|
2007-04-05 17:03:09 +00:00
|
|
|
++$errcount;
|
2006-01-08 20:03:08 +00:00
|
|
|
print STDERR "\n";
|
|
|
|
}
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
close IN;
|
|
|
|
}
|
|
|
|
|
|
|
|
# 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
|
|
|
|
# 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.
|
1999-04-24 13:28:57 +00:00
|
|
|
# Store all function and reason codes found in %ufcodes and %urcodes
|
|
|
|
# so all those unreferenced can be printed out.
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
foreach $file (@source) {
|
|
|
|
# Don't parse the error source file.
|
|
|
|
next if exists $cskip{$file};
|
2006-01-01 18:42:05 +00:00
|
|
|
print STDERR "File loaded: ".$file."\r" if $debug;
|
1999-04-24 11:23:20 +00:00
|
|
|
open(IN, "<$file") || die "Can't open source file $file\n";
|
2015-11-03 13:52:45 +00:00
|
|
|
my $func;
|
|
|
|
my $linenr = 0;
|
1999-04-24 00:15:18 +00:00
|
|
|
while(<IN>) {
|
2009-04-15 15:27:03 +00:00
|
|
|
# skip obsoleted source files entirely!
|
|
|
|
last if(/^#error\s+obsolete/);
|
2015-11-03 13:52:45 +00:00
|
|
|
$linenr++;
|
|
|
|
if (!/;$/ && /^\**([a-zA-Z_].*[\s*])?([A-Za-z_0-9]+)\(.*([),]|$)/)
|
|
|
|
{
|
|
|
|
/^([^()]*(\([^()]*\)[^()]*)*)\(/;
|
|
|
|
$1 =~ /([A-Za-z_0-9]*)$/;
|
|
|
|
$func = $1;
|
|
|
|
}
|
2009-04-15 15:27:03 +00:00
|
|
|
|
1999-04-24 13:28:57 +00:00
|
|
|
if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
|
1999-04-24 00:15:18 +00:00
|
|
|
next unless exists $csrc{$2};
|
|
|
|
next if($1 eq "BIO_F_BUFFER_CTX");
|
1999-04-24 13:28:57 +00:00
|
|
|
$ufcodes{$1} = 1;
|
1999-04-24 00:15:18 +00:00
|
|
|
if(!exists $fcodes{$1}) {
|
|
|
|
$fcodes{$1} = "X";
|
|
|
|
$fnew{$2}++;
|
|
|
|
}
|
2015-11-03 13:52:45 +00:00
|
|
|
$ftrans{$3} = $func unless exists $ftrans{$3};
|
|
|
|
if (uc $func ne $3) {
|
|
|
|
print STDERR "ERROR: mismatch $file:$linenr $func:$3\n";
|
|
|
|
$errcount++;
|
|
|
|
}
|
2009-04-15 15:27:03 +00:00
|
|
|
print STDERR "Function: $1\t= $fcodes{$1} (lib: $2, name: $3)\n" if $debug;
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
|
|
|
|
next unless exists $csrc{$2};
|
1999-04-24 13:28:57 +00:00
|
|
|
$urcodes{$1} = 1;
|
1999-04-24 00:15:18 +00:00
|
|
|
if(!exists $rcodes{$1}) {
|
|
|
|
$rcodes{$1} = "X";
|
|
|
|
$rnew{$2}++;
|
|
|
|
}
|
2009-04-15 15:27:03 +00:00
|
|
|
print STDERR "Reason: $1\t= $rcodes{$1} (lib: $2)\n" if $debug;
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
close IN;
|
|
|
|
}
|
2006-01-08 19:54:32 +00:00
|
|
|
print STDERR " \n" if $debug;
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
# Now process each library in turn.
|
|
|
|
|
|
|
|
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";
|
1999-04-24 17:28:43 +00:00
|
|
|
next unless $dowrite;
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# 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
|
|
|
|
|
2016-05-18 17:52:34 +00:00
|
|
|
$cpp = 0;
|
|
|
|
$cplusplus = 0;
|
2002-02-07 19:23:35 +00:00
|
|
|
if (open(IN, "<$hfile")) {
|
|
|
|
# Copy across the old file
|
|
|
|
while(<IN>) {
|
2016-05-18 17:52:34 +00:00
|
|
|
$cplusplus = $cpp if /^#.*ifdef.*cplusplus/;
|
|
|
|
$cpp++ if /^#\s*if/;
|
|
|
|
$cpp-- if /^#\s*endif/;
|
1999-04-24 00:15:18 +00:00
|
|
|
push @out, $_;
|
|
|
|
last if (/BEGIN ERROR CODES/);
|
2002-02-07 19:23:35 +00:00
|
|
|
}
|
|
|
|
close IN;
|
|
|
|
} else {
|
2016-05-18 17:52:34 +00:00
|
|
|
$cpp = 1;
|
|
|
|
$cplusplus = 1;
|
2002-02-07 19:23:35 +00:00
|
|
|
push @out,
|
2016-04-20 02:10:43 +00:00
|
|
|
"/*\n",
|
2016-05-01 12:47:43 +00:00
|
|
|
" * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved.\n",
|
2002-02-07 19:23:35 +00:00
|
|
|
" *\n",
|
2016-04-20 02:10:43 +00:00
|
|
|
" * 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",
|
2002-02-07 19:23:35 +00:00
|
|
|
" */\n",
|
|
|
|
"\n",
|
|
|
|
"#ifndef HEADER_${lib}_ERR_H\n",
|
2016-05-18 17:52:34 +00:00
|
|
|
"# define HEADER_${lib}_ERR_H\n",
|
2002-02-07 19:23:35 +00:00
|
|
|
"\n",
|
2016-05-18 17:52:34 +00:00
|
|
|
"# ifdef __cplusplus\n",
|
2008-04-17 10:19:16 +00:00
|
|
|
"extern \"C\" {\n",
|
2016-05-18 17:52:34 +00:00
|
|
|
"# endif\n",
|
2008-04-17 10:19:16 +00:00
|
|
|
"\n",
|
2002-02-07 19:23:35 +00:00
|
|
|
"/* BEGIN ERROR CODES */\n";
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
|
|
|
|
|
|
|
|
print OUT @out;
|
|
|
|
undef @out;
|
|
|
|
print OUT <<"EOF";
|
2015-03-06 13:00:47 +00:00
|
|
|
/*
|
2016-05-18 17:52:34 +00:00
|
|
|
* 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.
|
1999-04-24 00:15:18 +00:00
|
|
|
*/
|
2016-05-18 17:52:34 +00:00
|
|
|
|
2001-11-15 16:52:10 +00:00
|
|
|
EOF
|
|
|
|
if($static) {
|
|
|
|
print OUT <<"EOF";
|
2016-07-12 13:50:06 +00:00
|
|
|
${staticloader}int ERR_load_${lib}_strings(void);
|
2016-05-18 17:52:34 +00:00
|
|
|
|
2001-11-15 16:52:10 +00:00
|
|
|
EOF
|
|
|
|
} else {
|
|
|
|
print OUT <<"EOF";
|
2016-07-12 13:50:06 +00:00
|
|
|
${staticloader}int ERR_load_${lib}_strings(void);
|
2001-11-15 16:52:10 +00:00
|
|
|
${staticloader}void ERR_unload_${lib}_strings(void);
|
|
|
|
${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
|
2016-02-17 22:04:47 +00:00
|
|
|
# define ${lib}err(f,r) ERR_${lib}_error((f),(r),OPENSSL_FILE,OPENSSL_LINE)
|
2002-01-24 16:20:42 +00:00
|
|
|
|
2001-11-15 16:52:10 +00:00
|
|
|
EOF
|
|
|
|
}
|
|
|
|
print OUT <<"EOF";
|
1999-04-24 00:15:18 +00:00
|
|
|
/* Error codes for the $lib functions. */
|
|
|
|
|
|
|
|
/* Function codes. */
|
|
|
|
EOF
|
|
|
|
|
|
|
|
foreach $i (@function) {
|
2015-03-06 13:00:47 +00:00
|
|
|
$z=48 - length($i);
|
1999-04-24 00:15:18 +00:00
|
|
|
if($fcodes{$i} eq "X") {
|
2006-01-08 21:43:36 +00:00
|
|
|
$fassigned{$lib} =~ m/^:([^:]*):/;
|
|
|
|
$findcode = $1;
|
|
|
|
if (!defined($findcode)) {
|
|
|
|
$findcode = $fmax{$lib};
|
|
|
|
}
|
|
|
|
while ($fassigned{$lib} =~ m/:$findcode:/) {
|
|
|
|
$findcode++;
|
|
|
|
}
|
|
|
|
$fcodes{$i} = $findcode;
|
|
|
|
$fassigned{$lib} .= "$findcode:";
|
1999-04-24 00:15:18 +00:00
|
|
|
print STDERR "New Function code $i\n" if $debug;
|
|
|
|
}
|
2015-03-06 13:00:47 +00:00
|
|
|
printf OUT "# define $i%s $fcodes{$i}\n"," " x $z;
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
print OUT "\n/* Reason codes. */\n";
|
|
|
|
|
|
|
|
foreach $i (@reasons) {
|
2015-03-06 13:00:47 +00:00
|
|
|
$z=48 - length($i);
|
1999-04-24 00:15:18 +00:00
|
|
|
if($rcodes{$i} eq "X") {
|
2006-01-08 21:43:36 +00:00
|
|
|
$rassigned{$lib} =~ m/^:([^:]*):/;
|
|
|
|
$findcode = $1;
|
|
|
|
if (!defined($findcode)) {
|
|
|
|
$findcode = $rmax{$lib};
|
|
|
|
}
|
|
|
|
while ($rassigned{$lib} =~ m/:$findcode:/) {
|
|
|
|
$findcode++;
|
|
|
|
}
|
|
|
|
$rcodes{$i} = $findcode;
|
|
|
|
$rassigned{$lib} .= "$findcode:";
|
1999-04-24 00:15:18 +00:00
|
|
|
print STDERR "New Reason code $i\n" if $debug;
|
|
|
|
}
|
2015-03-06 13:00:47 +00:00
|
|
|
printf OUT "# define $i%s $rcodes{$i}\n"," " x $z;
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
print OUT <<"EOF";
|
|
|
|
|
|
|
|
EOF
|
2016-05-18 17:52:34 +00:00
|
|
|
do {
|
|
|
|
if ($cplusplus == $cpp) {
|
2016-05-18 20:15:30 +00:00
|
|
|
print OUT "#", " "x$cpp, "ifdef __cplusplus\n";
|
2016-05-18 17:52:34 +00:00
|
|
|
print OUT "}\n";
|
|
|
|
print OUT "#", " "x$cpp, "endif\n";
|
|
|
|
}
|
|
|
|
if ($cpp-- > 0) {
|
|
|
|
print OUT "#", " "x$cpp, "endif\n";
|
|
|
|
}
|
|
|
|
} while ($cpp);
|
1999-04-24 00:15:18 +00:00
|
|
|
close OUT;
|
|
|
|
|
|
|
|
# Rewrite the C source file containing the error details.
|
|
|
|
|
2000-03-05 00:19:36 +00:00
|
|
|
# First, read any existing reason string definitions:
|
|
|
|
my %err_reason_strings;
|
|
|
|
if (open(IN,"<$cfile")) {
|
Have mkerr.pl treat already existing multiline string defs properly
Since source reformat, we ended up with some error reason string
definitions that spanned two lines. That in itself is fine, but we
sometimes edited them to provide better strings than what could be
automatically determined from the reason macro, for example:
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),
"Peer haven't sent GOST certificate, required for selected ciphersuite"},
However, mkerr.pl didn't treat those two-line definitions right, and
they ended up being retranslated to whatever the macro name would
indicate, for example:
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),
"No gost certificate sent by peer"},
Clearly not what we wanted. This change fixes this problem.
Reviewed-by: Matt Caswell <matt@openssl.org>
2015-04-08 17:26:11 +00:00
|
|
|
my $line = "";
|
2000-03-05 00:19:36 +00:00
|
|
|
while (<IN>) {
|
Perl's chop / chomp considered bad, use a regexp instead
Once upon a time, there was chop, which somply chopped off the last
character of $_ or a given variable, and it was used to take off the
EOL character (\n) of strings.
... but then, you had to check for the presence of such character.
So came chomp, the better chop which checks for \n before chopping it
off. And this worked well, as long as Perl made internally sure that
all EOLs were converted to \n.
These days, though, there seems to be a mixture of perls, so lines
from files in the "wrong" environment might have \r\n as EOL, or just
\r (Mac OS, unless I'm misinformed).
So it's time we went for the more generic variant and use s|\R$||, the
better chomp which recognises all kinds of known EOLs and chops them
off.
A few chops were left alone, as they are use as surgical tools to
remove one last slash or one last comma.
NOTE: \R came with perl 5.10.0. It means that from now on, our
scripts will fail with any older version.
Reviewed-by: Rich Salz <rsalz@openssl.org>
2016-02-11 20:47:30 +00:00
|
|
|
s|\R$||; # Better chomp
|
Have mkerr.pl treat already existing multiline string defs properly
Since source reformat, we ended up with some error reason string
definitions that spanned two lines. That in itself is fine, but we
sometimes edited them to provide better strings than what could be
automatically determined from the reason macro, for example:
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),
"Peer haven't sent GOST certificate, required for selected ciphersuite"},
However, mkerr.pl didn't treat those two-line definitions right, and
they ended up being retranslated to whatever the macro name would
indicate, for example:
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),
"No gost certificate sent by peer"},
Clearly not what we wanted. This change fixes this problem.
Reviewed-by: Matt Caswell <matt@openssl.org>
2015-04-08 17:26:11 +00:00
|
|
|
$_ = $line . $_;
|
|
|
|
$line = "";
|
|
|
|
if (/{ERR_(FUNC|REASON)\(/) {
|
|
|
|
if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
|
|
|
|
$err_reason_strings{$1} = $2;
|
|
|
|
} elsif (/\b${lib}_F_(\w*)\b.*\"(.*)\"/) {
|
|
|
|
if (!exists $ftrans{$1} && ($1 ne $2)) {
|
|
|
|
print STDERR "WARNING: Mismatched function string $2\n";
|
|
|
|
$ftrans{$1} = $2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$line = $_;
|
2006-11-21 21:29:44 +00:00
|
|
|
}
|
|
|
|
}
|
2000-03-05 00:19:36 +00:00
|
|
|
}
|
|
|
|
close(IN);
|
|
|
|
}
|
|
|
|
|
2006-11-21 21:29:44 +00:00
|
|
|
|
1999-06-22 13:33:22 +00:00
|
|
|
my $hincf;
|
|
|
|
if($static) {
|
2016-05-18 17:52:34 +00:00
|
|
|
$hincf = $hfile;
|
|
|
|
$hincf =~ s|.*include/||;
|
|
|
|
if ($hincf =~ m|^openssl/|) {
|
|
|
|
$hincf = "<${hincf}>";
|
|
|
|
} else {
|
|
|
|
$hincf = "\"${hincf}\"";
|
|
|
|
}
|
1999-06-22 13:33:22 +00:00
|
|
|
} else {
|
|
|
|
$hincf = "\"$hfile\"";
|
|
|
|
}
|
|
|
|
|
2005-04-12 13:31:14 +00:00
|
|
|
# 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}";
|
|
|
|
}
|
|
|
|
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
open (OUT,">$cfile") || die "Can't open $cfile for writing";
|
|
|
|
|
|
|
|
print OUT <<"EOF";
|
2016-04-20 02:10:43 +00:00
|
|
|
/*
|
2016-05-01 12:47:43 +00:00
|
|
|
* Generated by util/mkerr.pl DO NOT EDIT
|
|
|
|
* Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved.
|
1999-04-24 00:15:18 +00:00
|
|
|
*
|
2016-04-20 02:10:43 +00:00
|
|
|
* 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
|
1999-04-24 00:15:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <openssl/err.h>
|
1999-06-22 13:33:22 +00:00
|
|
|
#include $hincf
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
/* BEGIN ERROR CODES */
|
2001-02-21 12:03:20 +00:00
|
|
|
#ifndef OPENSSL_NO_ERR
|
2005-04-12 13:31:14 +00:00
|
|
|
|
2015-03-06 13:00:47 +00:00
|
|
|
# define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
|
|
|
|
# define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
|
2005-04-12 13:31:14 +00:00
|
|
|
|
2015-03-06 13:00:47 +00:00
|
|
|
static ERR_STRING_DATA ${lib}_str_functs[] = {
|
1999-04-24 00:15:18 +00:00
|
|
|
EOF
|
|
|
|
# Add each function code: if a function name is found then use it.
|
|
|
|
foreach $i (@function) {
|
|
|
|
my $fn;
|
|
|
|
$i =~ /^${lib}_F_(\S+)$/;
|
|
|
|
$fn = $1;
|
|
|
|
if(exists $ftrans{$fn}) {
|
|
|
|
$fn = $ftrans{$fn};
|
|
|
|
}
|
2005-04-12 13:31:14 +00:00
|
|
|
# print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
|
2016-05-18 17:52:34 +00:00
|
|
|
if(length($i) + length($fn) > 57) {
|
2015-03-06 13:00:47 +00:00
|
|
|
print OUT " {ERR_FUNC($i),\n \"$fn\"},\n";
|
|
|
|
} else {
|
|
|
|
print OUT " {ERR_FUNC($i), \"$fn\"},\n";
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
print OUT <<"EOF";
|
2015-03-06 13:00:47 +00:00
|
|
|
{0, NULL}
|
|
|
|
};
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2015-03-06 13:00:47 +00:00
|
|
|
static ERR_STRING_DATA ${lib}_str_reasons[] = {
|
1999-04-24 00:15:18 +00:00
|
|
|
EOF
|
|
|
|
# Add each reason code.
|
|
|
|
foreach $i (@reasons) {
|
|
|
|
my $rn;
|
2005-04-12 13:31:14 +00:00
|
|
|
my $rstr = "ERR_REASON($i)";
|
2000-03-05 00:19:36 +00:00
|
|
|
if (exists $err_reason_strings{$i}) {
|
|
|
|
$rn = $err_reason_strings{$i};
|
|
|
|
} else {
|
|
|
|
$i =~ /^${lib}_R_(\S+)$/;
|
|
|
|
$rn = $1;
|
|
|
|
$rn =~ tr/_[A-Z]/ [a-z]/;
|
|
|
|
}
|
2016-05-18 17:52:34 +00:00
|
|
|
if(length($i) + length($rn) > 55) {
|
2015-03-06 13:00:47 +00:00
|
|
|
print OUT " {${rstr},\n \"$rn\"},\n";
|
|
|
|
} else {
|
|
|
|
print OUT " {${rstr}, \"$rn\"},\n";
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
if($static) {
|
|
|
|
print OUT <<"EOF";
|
2015-03-06 13:00:47 +00:00
|
|
|
{0, NULL}
|
|
|
|
};
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2016-07-12 13:50:06 +00:00
|
|
|
${staticloader}int ERR_load_${lib}_strings(void)
|
2015-03-06 13:00:47 +00:00
|
|
|
{
|
2006-11-21 21:29:44 +00:00
|
|
|
#ifndef OPENSSL_NO_ERR
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2015-03-06 13:00:47 +00:00
|
|
|
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);
|
|
|
|
}
|
2006-11-21 21:29:44 +00:00
|
|
|
#endif
|
2016-07-12 13:50:06 +00:00
|
|
|
return 1;
|
2015-03-06 13:00:47 +00:00
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
EOF
|
|
|
|
} else {
|
|
|
|
print OUT <<"EOF";
|
2015-03-06 13:00:47 +00:00
|
|
|
{0, NULL}
|
|
|
|
};
|
1999-04-24 00:15:18 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ${lib}_LIB_NAME
|
2015-03-06 13:00:47 +00:00
|
|
|
static ERR_STRING_DATA ${lib}_lib_name[] = {
|
|
|
|
{0, ${lib}_LIB_NAME},
|
|
|
|
{0, NULL}
|
|
|
|
};
|
1999-04-24 00:15:18 +00:00
|
|
|
#endif
|
|
|
|
|
2015-03-06 13:00:47 +00:00
|
|
|
static int ${lib}_lib_error_code = 0;
|
|
|
|
static int ${lib}_error_init = 1;
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2016-07-12 13:50:06 +00:00
|
|
|
${staticloader}int ERR_load_${lib}_strings(void)
|
2015-03-06 13:00:47 +00:00
|
|
|
{
|
|
|
|
if (${lib}_lib_error_code == 0)
|
|
|
|
${lib}_lib_error_code = ERR_get_next_error_library();
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2015-03-06 13:00:47 +00:00
|
|
|
if (${lib}_error_init) {
|
|
|
|
${lib}_error_init = 0;
|
2001-02-21 12:03:20 +00:00
|
|
|
#ifndef OPENSSL_NO_ERR
|
2015-03-06 13:00:47 +00:00
|
|
|
ERR_load_strings(${lib}_lib_error_code, ${lib}_str_functs);
|
|
|
|
ERR_load_strings(${lib}_lib_error_code, ${lib}_str_reasons);
|
1999-04-24 00:15:18 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ${lib}_LIB_NAME
|
2015-03-06 13:00:47 +00:00
|
|
|
${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code, 0, 0);
|
|
|
|
ERR_load_strings(0, ${lib}_lib_name);
|
1999-12-23 02:02:42 +00:00
|
|
|
#endif
|
2015-03-06 13:00:47 +00:00
|
|
|
}
|
2016-07-12 13:50:06 +00:00
|
|
|
return 1;
|
2015-03-06 13:00:47 +00:00
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
|
2001-11-15 16:52:10 +00:00
|
|
|
${staticloader}void ERR_unload_${lib}_strings(void)
|
2015-03-06 13:00:47 +00:00
|
|
|
{
|
|
|
|
if (${lib}_error_init == 0) {
|
2001-11-15 16:52:10 +00:00
|
|
|
#ifndef OPENSSL_NO_ERR
|
2015-03-06 13:00:47 +00:00
|
|
|
ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_functs);
|
|
|
|
ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_reasons);
|
2001-11-15 16:52:10 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ${lib}_LIB_NAME
|
2015-03-06 13:00:47 +00:00
|
|
|
ERR_unload_strings(0, ${lib}_lib_name);
|
2001-11-15 16:52:10 +00:00
|
|
|
#endif
|
2015-03-06 13:00:47 +00:00
|
|
|
${lib}_error_init = 1;
|
|
|
|
}
|
|
|
|
}
|
2001-11-15 16:52:10 +00:00
|
|
|
|
|
|
|
${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
|
2015-03-06 13:00:47 +00:00
|
|
|
{
|
|
|
|
if (${lib}_lib_error_code == 0)
|
|
|
|
${lib}_lib_error_code = ERR_get_next_error_library();
|
|
|
|
ERR_PUT_error(${lib}_lib_error_code, function, reason, file, line);
|
|
|
|
}
|
1999-04-24 00:15:18 +00:00
|
|
|
EOF
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
close OUT;
|
2000-03-05 00:19:36 +00:00
|
|
|
undef %err_reason_strings;
|
1999-04-24 00:15:18 +00:00
|
|
|
}
|
|
|
|
|
2011-12-27 14:39:13 +00:00
|
|
|
if($debug && %notrans) {
|
1999-04-24 00:15:18 +00:00
|
|
|
print STDERR "The following function codes were not translated:\n";
|
1999-04-24 13:28:57 +00:00
|
|
|
foreach(sort keys %notrans)
|
|
|
|
{
|
|
|
|
print STDERR "$_\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Make a list of unreferenced function and reason codes
|
|
|
|
|
|
|
|
foreach (keys %fcodes) {
|
|
|
|
push (@funref, $_) unless exists $ufcodes{$_};
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (keys %rcodes) {
|
|
|
|
push (@runref, $_) unless exists $urcodes{$_};
|
|
|
|
}
|
|
|
|
|
2015-12-22 19:20:11 +00:00
|
|
|
if($unref && @funref) {
|
1999-04-24 13:28:57 +00:00
|
|
|
print STDERR "The following function codes were not referenced:\n";
|
|
|
|
foreach(sort @funref)
|
|
|
|
{
|
|
|
|
print STDERR "$_\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-22 19:20:11 +00:00
|
|
|
if($unref && @runref) {
|
1999-04-24 13:28:57 +00:00
|
|
|
print STDERR "The following reason codes were not referenced:\n";
|
|
|
|
foreach(sort @runref)
|
1999-04-24 00:15:18 +00:00
|
|
|
{
|
|
|
|
print STDERR "$_\n";
|
|
|
|
}
|
|
|
|
}
|
2007-04-05 17:03:09 +00:00
|
|
|
|
|
|
|
if($errcount) {
|
|
|
|
print STDERR "There were errors, failing...\n\n";
|
|
|
|
exit $errcount;
|
|
|
|
}
|
|
|
|
|