# 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;