Browse Source

Make checkSpace.pl check guard macros:

  - every .h file needs an #ifndef/#define pair.
  - They must refer to the same macro.
  - The guard macros that they refer to must be unique across all headers.
Nick Mathewson 5 years ago
parent
commit
95209be861
2 changed files with 35 additions and 0 deletions
  1. 3 0
      changes/ticket29756
  2. 32 0
      scripts/maint/checkSpace.pl

+ 3 - 0
changes/ticket29756

@@ -0,0 +1,3 @@
+  o Minor features (developer tools):
+    - Add a script to check that each header has a well-formed and unique
+      guard marco. Closes ticket 29756.

+ 32 - 0
scripts/maint/checkSpace.pl

@@ -18,6 +18,8 @@ if ($ARGV[0] =~ /^-/) {
 
 our %basenames = ();
 
+our %guardnames = ();
+
 for my $fn (@ARGV) {
     open(F, "$fn");
     my $lastnil = 0;
@@ -31,6 +33,10 @@ for my $fn (@ARGV) {
     } else {
         $basenames{$basename} = $fn;
     }
+    my $isheader = ($fn =~ /\.h/);
+    my $seenguard = 0;
+    my $guardname = "<none>";
+
     while (<F>) {
         ## Warn about windows-style newlines.
         #    (We insist on lines that end with a single LF character, not
@@ -112,6 +118,23 @@ for my $fn (@ARGV) {
                     next;
                 }
             }
+
+            if ($isheader) {
+                if ($seenguard == 0) {
+                    if (/ifndef\s+(\S+)/) {
+                        ++$seenguard;
+                        $guardname = $1;
+                    }
+                } elsif ($seenguard == 1) {
+                    if (/^\#define (\S+)/) {
+                        ++$seenguard;
+                        if ($1 ne $guardname) {
+                            msg "GUARD:$fn:$.: Header guard macro mismatch.\n";
+                        }
+                    }
+                }
+            }
+
             if (m!/\*.*?\*/!) {
                 s!\s*/\*.*?\*/!!;
             } elsif (m!/\*!) {
@@ -201,6 +224,15 @@ for my $fn (@ARGV) {
             }
         }
     }
+    if ($isheader && $C) {
+        if ($seenguard < 2) {
+            msg "$fn:No #ifndef/#define header guard pair found.\n";
+        } elsif ($guardnames{$guardname}) {
+            msg "$fn:Guard macro $guardname also used in $guardnames{$guardname}\n";
+        } else {
+            $guardnames{$guardname} = $fn;
+        }
+    }
     close(F);
 }