# New Ticket Created by  Mark Glines 
# Please include the string:  [perl #42916]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=42916 >


c_header_guards.t determines its list of header files to check from the
command line, if available, and by querying Parrot::Distribution
otherwise.  It tries pretty hard to get a list of headers; it starts by
calling c_header_files(), and then follows that up with entries from
generated_files(), too.  But the resulting list is still missing a few
entries, when compared to a "find -type f -name '*.h'" on my linux
box.  A few things are generated yet not listed in generated_files(),
and a few headers are simply copied from one directory to another.

The copied files could theoretically trigger a guard-name collision
failure, so that test was TODOed out.  But, with the list of files
reported by Parrot::Distribution, c_header_guards.t passes all tests on
my machine, so I'm not sure the TODO flag was actually necessary to
begin with.  Either way, I have a fix for the test.

Here's what the failures look like:

[EMAIL PROTECTED] ~/parrot-endif $ perl t/codingstd/c_header_guards.t
`find -type f -name '*.h'`
1..5
not ok 1 - identical PARROT_*_GUARD macro names used in headers # TODO
Need to account for headers copied between subdirs 
#     Failed (TODO) test (t/codingstd/c_header_guards.t at line 121)
# collisions: # ./src/exec_dep.h,
# ./src/jit/i386/exec_dep.h,
# ./src/jit_emit.h,
# ./src/jit/i386/jit_emit.h
ok 2 - multiple PARROT_*_GUARD macros found in headers

These files are simply copies of eachother, verifiable with md5sum.  The
first attached patch (check_header_file_duplicity.diff) cleans this
test failure up - if the text from each file is identical, then I think
it's safe to assume identical guard macros are not actually a problem,
because you'll get the same namespace stuff no matter which one you
included.  Now that this is cleaned up, I believe it is safe to un-TODO
the collision test, so this patch removes the TODOness, too.



As you can see below, there are *still* a couple of autogenerated
headers which fail the guard checks.  These files are not reported by
$DIST->c_header_files() or $DIST->generated_files(), which is why I
didn't notice them until now.

not ok 3 - missing or misspelled PARROT_*_GUARD ifndef in headers
#     Failed test (t/codingstd/c_header_guards.t at line 130)
# missing guard:
# ./compilers/pge/PGE/pmc/pge.h,
# ./src/dynpmc/match_group.h
not ok 4 - missing or misspelled PARROT_*_GUARD define in headers
#     Failed test (t/codingstd/c_header_guards.t at line 134)
# missing define:
# ./compilers/pge/PGE/pmc/pge.h,
# ./src/dynpmc/match_group.h
not ok 5 - missing or misspelled PARROT_*_GUARD comment after the endif
in headers
#     Failed test (t/codingstd/c_header_guards.t at line 138)
# missing endif comment:
# ./compilers/pge/PGE/pmc/pge.h,
# ./src/dynpmc/match_group.h
# Looks like you failed 3 tests of 5.

The second attached patch (pmc2c_more_header_guards.diff) cleans these
up.  With these two patches, c_header_guards.t passes on every .h file
in the tree.  Or at least, every header that got generated for a
default configuration on my i386-linux box.

Whether Parrot::Distribution should have reported the extra headers or
not is sort of an open question.  If someone thinks it's important, I'll
work on it.

Mark
Index: t/codingstd/c_header_guards.t
===================================================================
--- t/codingstd/c_header_guards.t	(revision 18488)
+++ t/codingstd/c_header_guards.t	(working copy)
@@ -92,8 +92,11 @@
                 $redundants{$file} = $1 if defined $ifndef;
 
                 # check for the same guard-name in multiple files
-                $collisions{$file} = $guardnames{$1}
-                    if exists $guardnames{$1};
+                if(exists($guardnames{$1})) {
+                    if(!duplicate_files($file, $guardnames{$1})) {
+                        $collisions{$file} = $guardnames{$1};
+                    }
+                }
 
                 $ifndef = $1;
                 $guardnames{$1} = $file;
@@ -115,13 +118,9 @@
         $missing_comment{$file} = 1 unless defined $endif;
     }
 
-TODO: {
-    local $TODO = "Need to account for headers copied between subdirs";
-
     ok(!(scalar %collisions), "identical PARROT_*_GUARD macro names used in headers");
     diag("collisions: \n" . join(", \n", %collisions))
         if scalar keys %collisions;
-};
 
     ok(!(scalar %redundants), "multiple PARROT_*_GUARD macros found in headers");
     diag("redundants: \n" . join(", \n", keys %redundants))
@@ -142,6 +141,18 @@
     return 0;
 }
 
+sub duplicate_files {
+    my ($file1, $file2) = @_;
+    open my $fh1, '<', $file1
+        or die "Cannot open '$file1' for reading!\n";
+    open my $fh2, '<', $file2
+        or die "Cannot open '$file2' for reading!\n";
+    local $/;
+    $file1 = <$fh1>;
+    $file2 = <$fh2>;
+    return $file1 eq $file2;
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4
Index: lib/Parrot/Pmc2c/Library.pm
===================================================================
--- lib/Parrot/Pmc2c/Library.pm	(revision 18488)
+++ lib/Parrot/Pmc2c/Library.pm	(working copy)
@@ -119,9 +119,17 @@
     my ($self)     = @_;
     my $hout       = dont_edit('various files');
     my $lc_libname = lc $self->{opt}{library};
+    my $guardname  = uc(join('_', 'PARROT_LIB', $lc_libname, 'H_GUARD'));
 
     $hout .= <<"EOH";
+
+#ifndef $guardname
+#define $guardname
+
 Parrot_PMC Parrot_lib_${lc_libname}_load(Parrot_Interp interp);
+
+#endif /* $guardname */
+
 EOH
     $hout .= $self->c_code_coda;
 

Reply via email to