Author: paultcochrane
Date: Tue May  8 07:43:52 2007
New Revision: 18462

Added:
   trunk/t/codingstd/c_header_guards.t   (contents, props changed)

Log:
[codingstd] New test which tests for guard macro names and preprocessor
directives in header files.  
Courtesty of Mark Glines <mark at glines dot org>


Added: trunk/t/codingstd/c_header_guards.t
==============================================================================
--- (empty file)
+++ trunk/t/codingstd/c_header_guards.t Tue May  8 07:43:52 2007
@@ -0,0 +1,129 @@
+#! perl
+# Copyright (C) 2006-2007, The Perl Foundation.
+# $Id$
+
+use strict;
+use warnings;
+
+use lib qw( . lib ../lib ../../lib );
+use Test::More tests => 5;
+use Parrot::Distribution;
+
+=head1 NAME
+
+t/codingstd/c_header_guards.t - checks for rules related to guards in C header 
files
+
+=head1 SYNOPSIS
+
+    # test all files
+    % prove t/codingstd/c_header_guards.t
+
+    # test specific files
+    % perl t/codingstd/c_header_guards.t include/parrot/bar.h
+
+=head1 DESCRIPTION
+
+Checks that all C language header files have an #ifndef PARROT_WHATEVER_H_GUARD
+definition, and an #endif /* PARROT_WHATEVER_H_GUARD */ at the end, as
+specified in PDD07.
+
+=head1 AUTHOR
+
+Mark Glines <mark at glines dot org>
+
+=head1 SEE ALSO
+
+L<docs/pdds/pdd07_codingstd.pod>
+
+=cut
+
+my $DIST = Parrot::Distribution->new();
+my @files = @ARGV ? @ARGV : map { $_->path() } $DIST->c_header_files();
+
+check_header_guards(@files);
+
+exit;
+
+sub check_header_guards {
+    my (%guardnames, %redundants, %collisions,
+        %missing_guard, %missing_define, %missing_comment);
+
+F:  foreach my $file (@_) {
+        open my $fh, '<', $file
+            or die "Cannot open '$file' for reading!\n";
+        my @source = <$fh>;
+        close $fh;
+        chomp @source;
+
+        my ($ifndef, $define, $endif);
+L:          foreach my $line (@source) {
+            $line =~ s/\s+/ /;
+            $line =~ s/^ //;
+
+            # skip Bison parser files
+            next F if $line =~ /A Bison parser/;
+
+            # skip the non-preprocessor lines
+            next L unless substr($line,0,1) eq '#';
+
+            # skip the "#", and any leading whitespace
+            $line = substr($line, 1);
+            $line =~ s/^ //;
+
+            if($line =~ m{ifndef (PARROT_.+_GUARD)$}) {
+                # check for multiple guards in the same file
+                $redundants{$file} = $1 if defined $ifndef;
+                # check for the same guard-name in multiple files
+                $collisions{$file} = $guardnames{$1}
+                    if exists $guardnames{1};
+
+                $ifndef = $1;
+                $guardnames{$1} = $file;
+            }
+
+            if($line =~ m{define (PARROT_.+_GUARD)$}) {
+                $define = $1
+                    if(defined($ifndef) && $ifndef eq $1);
+            }
+
+            if($line =~ m{endif /\* (PARROT_.+_GUARD) \*/$}) {
+                $endif = $1
+                    if(defined($ifndef) && $ifndef eq $1);
+            }
+        }
+
+        $missing_guard{$file}   = 1 unless defined $ifndef;
+        $missing_define{$file}  = 1 unless defined $define;
+        $missing_comment{$file} = 1 unless defined $endif;
+    }
+
+    ok(!(scalar %collisions), "identical PARROT_*_GUARD macro names used in 
headers");
+    diag("collisions: " . join(", ", %collisions))
+        if scalar keys %collisions;
+
+    ok(!(scalar %redundants), "multiple PARROT_*_GUARD macros found in 
headers");
+    diag("redundants: " . join(", ", keys %redundants))
+        if scalar keys %redundants;
+
+    ok(!(scalar %missing_guard), "missing or misspelled PARROT_*_GUARD ifndef 
in headers");
+    diag("missing guard: " . join(", ", sort keys %missing_guard))
+        if scalar keys %missing_guard;
+
+    ok(!(scalar %missing_define), "missing or misspelled PARROT_*_GUARD define 
in headers");
+    diag("missing define: " . join(", ", sort keys %missing_define))
+        if scalar keys %missing_define;
+
+    ok(!(scalar %missing_comment), "missing or misspelled PARROT_*_GUARD 
comment after the endif in headers");
+    diag("missing endif comment: " . join(", ", sort keys %missing_comment))
+        if scalar keys %missing_comment;
+
+    return 0;
+}
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+

Reply via email to