check calling conventions specified for Windows
authorKen Raeburn <raeburn@mit.edu>
Thu, 29 Jun 2006 01:42:42 +0000 (01:42 +0000)
committerKen Raeburn <raeburn@mit.edu>
Thu, 29 Jun 2006 01:42:42 +0000 (01:42 +0000)
When we're making changes on UNIX, sometimes we update the Windows
export list but forget to make sure we've annotated the function
declaration in the header file with a calling convention
specification.

This patch checks the krb5 and gssapi public headers against the
Windows export lists (which are annotated with calling-convention and
other info in comments), and flags any inconsistencies in public
interfaces.

* util/def-check.pl: Be quiet about normal stuff by default; accept a
"-v" option to be verbose.  Exit with non-zero status if something
wrong is detected.  Fix some problems in parsing gssapi header files.
Handle DECSCRIPTION and HEAPSIZE directives in .def files, and DATA
annotation in comments.

* include/Makefile.in (verify-calling-conventions-krb5): New target.
(all-unix): Depend on it in maintainer mode.

* lib/gssapi/Makefile.in (verify-calling-conventions-gssapi): New target.
(all-unix): Depend on it in maintainer mode.
(merged-gssapi-header.h): New target; assemble public headers into one input
file.
(clean-misc-unix): New target; delete merged-gssapi-header.h.
(clean-unix): Depend on it.

ticket: new

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18258 dc483132-0cff-0310-8789-dd5450dbe970

src/include/Makefile.in
src/lib/gssapi/Makefile.in
src/util/def-check.pl

index 313a01782176a3be9de50efd1a7e72d9521df254..d1c6b4251d3d9feb1c7eb2ccbb440cc6b92ac914 100644 (file)
@@ -26,6 +26,8 @@ BUILT_HEADERS = osconf.h
 all-unix:: autoconf.h $(BUILT_HEADERS)
 all-windows:: autoconf.h $(BUILT_HEADERS)
 
+all-unix:: @MAINT@ verify-calling-conventions-krb5
+
 $(srcdir)/autoconf.h.in: @MAINT@ $(srcdir)/autoconf.stmp
 $(srcdir)/autoconf.stmp: $(srcdir)/$(thisconfigdir)/configure.in $(SRCTOP)/aclocal.m4
        $(RM) -r $(srcdir)/$(thisconfigdir)/autom4te.cache
@@ -80,6 +82,9 @@ krb5/krb5.h: $(srcdir)/krb5/krb5.hin krb5_err.h kdb5_err.h kv5m_err.h krb524_err
        cat $(srcdir)/krb5/krb5.hin krb5_err.h kdb5_err.h kv5m_err.h krb524_err.h \
                asn1_err.h >> krb5/krb5.h
 
+verify-calling-conventions-krb5: krb5/krb5.h
+       $(PERL) -w $(SRCTOP)/util/def-check.pl krb5/krb5.h $(SRCTOP)/lib/krb5_32.def
+
 #
 # Build the error table include files:
 # asn1_err.h kdb5_err.h krb5_err.h kv5m_err.h krb524_err.h
index b8568c7d521da7b61edf8d213f9ef4717150b92c..20012fe6309fd6ab8500898cf753f0622a397e89 100644 (file)
@@ -38,15 +38,30 @@ SHLIB_DIRS=-L$(TOPLIBD)
 SHLIB_RDIRS=$(KRB5_LIBDIR)
 RELDIR=gssapi
 
-all-unix:: all-liblinks
+all-unix:: all-liblinks @MAINT@ verify-calling-conventions-gssapi
 
 install-unix:: install-libs
 
-clean-unix:: clean-liblinks clean-libs clean-libobjs
+clean-unix:: clean-liblinks clean-libs clean-libobjs clean-misc-unix
 
 clean-windows::
        $(RM) gssapi.lib gssapi.bak
 
+clean-misc-unix:
+       $(RM) merged-gssapi-header.h
+
+EHDRDIR=$(BUILDTOP)$(S)include$(S)gssapi
+EXPORTED_HEADERS= \
+       $(EHDRDIR)$(S)gssapi_krb5.h \
+       $(EHDRDIR)$(S)gssapi_generic.h \
+       $(EHDRDIR)$(S)gssapi.h
+$(EXPORTED_HEADERS): all-recurse
+merged-gssapi-header.h: $(EXPORTED_HEADERS)
+       cat $(EXPORTED_HEADERS) > merged.tmp
+       $(MV) merged.tmp merged-gssapi-header.h
+verify-calling-conventions-gssapi: merged-gssapi-header.h
+       $(PERL) -w $(SRCTOP)/util/def-check.pl merged-gssapi-header.h $(srcdir)/../gssapi32.def
+
 all-windows::
        cd generic
        @echo Making in gssapi\generic
index 447421e8e792ea0b50bc046ad29aee081d087215..b007c9cecd963c637fcb898cb8d8b20015f80c2f 100644 (file)
@@ -9,7 +9,10 @@ eval 'exec /usr/athena/bin/perl -S $0 ${1+"$@"}'
 use strict;
 use IO::File;
 
-my $h_filename = shift @ARGV || die "usage: $0 header-file [def-file]\n";
+my $verbose = 0;
+my $error = 0;
+if ( $ARGV[0] eq "-v" ) { $verbose = 1; shift @ARGV; }
+my $h_filename = shift @ARGV || die "usage: $0 [-v] header-file [def-file]\n";
 my $d_filename = shift @ARGV;
 
 my $h = open_always($h_filename);
@@ -47,14 +50,12 @@ while (! $h->eof()) {
     }
   Top:
     # drop KRB5INT_BEGIN_DECLS and KRB5INT_END_DECLS
-    if (/^ *KRB5INT_BEGIN_DECLS/) {
-        next LINE;
-    }
-    if (/^ *KRB5INT_END_DECLS/) {
+    if (/^ *(KRB5INT|GSSAPI[A-Z]*)_(BEGIN|END)_DECLS/) {
         next LINE;
     }
     # drop preprocessor directives
     if (/^ *#/) {
+       while (/\\$/) { $_ .= $h->getline(); }
         next LINE;
     }
     if (/^ *\?==/) {
@@ -75,7 +76,7 @@ while (! $h->eof()) {
     }
     # multi-line comments?
     if (/\/\*$/) {
-       $_ .= "\n";
+       $_ .= " ";
        $len1 = length;
        $_ .= $h->getline();
        chop if $len1 < length;
@@ -85,7 +86,7 @@ while (! $h->eof()) {
     if (/^[ \t]*$/) {
         next LINE;
     }
-    if (/ *extern "C" {/) {
+    if (/^ *extern "C" {/) {
         next LINE;
     }
     # elide struct definitions
@@ -180,11 +181,13 @@ while (! $h->eof()) {
     }
 }
 
-print join("\n\t", "Using default calling convention:", sort(@convD));
-print join("\n\t", "\nUsing KRB5_CALLCONV:", sort(@convK));
-print join("\n\t", "\nUsing KRB5_CALLCONV_C:", sort(@convC));
-print join("\n\t", "\nUsing KRB5_CALLCONV_WRONG:", sort(@convW));
-print "\n","-"x70,"\n";
+if ( $verbose ) {
+    print join("\n\t", "Using default calling convention:", sort(@convD));
+    print join("\n\t", "\nUsing KRB5_CALLCONV:", sort(@convK));
+    print join("\n\t", "\nUsing KRB5_CALLCONV_C:", sort(@convC));
+    print join("\n\t", "\nUsing KRB5_CALLCONV_WRONG:", sort(@convW));
+    print "\n","-"x70,"\n";
+}
 
 %conv = ();
 map { $conv{$_} = "default"; } @convD;
@@ -196,8 +199,8 @@ my %vararg = ();
 map { $vararg{$_} = 1; } @vararg;
 
 if (!$d) {
-    print "No .DEF file specified\n";
-    exit;
+    print "No .DEF file specified\n" if $verbose;
+    exit 0;
 }
 
 LINE2:
@@ -213,7 +216,7 @@ while (! $d->eof()) {
         $printit = 0;
         next LINE2;
     }
-    if (/^EXPORTS/) {
+    if (/^EXPORTS/ || /^DESCRIPTION/ || /^HEAPSIZE/) {
         $printit = 0;
         next LINE2;
     }
@@ -221,6 +224,8 @@ while (! $d->eof()) {
     my($xconv);
     if (/PRIVATE/ || /INTERNAL/) {
        $xconv = "PRIVATE";
+    } elsif (/DATA/) {
+       $xconv = "DATA";
     } elsif (/!CALLCONV/ || /KRB5_CALLCONV_WRONG/) {
        $xconv = "KRB5_CALLCONV_WRONG";
     } elsif ($vararg{$_}) {
@@ -231,16 +236,23 @@ while (! $d->eof()) {
     s/;.*$//;
 
     if ($xconv eq "PRIVATE") {
-       print "\t private $_\n";
+       print "\t private $_\n" if $verbose;
+       next LINE2;
+    }
+    if ($xconv eq "DATA") {
+       print "\t data $_\n" if $verbose;
        next LINE2;
     }
     if (!defined($conv{$_})) {
        print "No calling convention specified for $_!\n";
+       $error = 1;
     } elsif (! ($conv{$_} eq $xconv)) {
        print "Function $_ should have calling convention '$xconv', but has '$conv{$_}' instead.\n";
+       $error = 1;
     } else {
 #      print "Function $_ is okay.\n";
     }
 }
 
 #print "Calling conventions defined for: ", keys(%conv);
+exit $error;