#!/usr/bin/perl -I /afs/cern.ch/user/l/leggett/lib/perl use File::Basename; use Script; $sys = 0; while($#ARGV >= 0) { $_ = shift; SWITCH: { if (/^-/) { ($l,@opts) = &OptExpL($_); foreach (@opts) { OPTS: { if ($l == 1) { if (/help/) {&Help(1); exit(0);} if (/debug/) {$__DEBUG__++; last OPTS; } if (/sys/) {$sys = 1; last OPTS; } if (/list/) {$list = 1; last OPTS; } if (/quiet/) {$quiet = 1; last OPTS; } print &Error("unknown option \"--$_\"\n"); } else { if (/h/) {&Help(1); exit(0);} if (/d/) {$__DEBUG__++; last OPTS; } if (/s/) {$sys = 1; last OPTS; } if (/l/) {$list = 1; last OPTS; } if (/q/) {$quiet = 1; last OPTS; } print &Error("unknown option \"-$_\"\n"); } exit(1); } } last SWITCH;} push(@files,$_); } } if ($#files < 0 && !$list) { &Help(0); exit(0); } $package = `cmt show macro_value package`; chop $package; if ($package eq "") { print &Error("running cmt command. Is cmt in your path?\n"); exit(1); } push (@incDirs,"."); push (@incDirs,".."); if ($sys) { $gpp = `which g++`; $ginc = dirname($gpp); $ginc = dirname($ginc) . "/include"; if ($gpp =~ /2.95/) { $ginc .= "/g++"; } elsif ($gpp =~ /3.2/) { $ginc .= "/c++/3.2"; } else { print &Warn("Can't find system c++ include files\n"); undef $ginc; } push (@incDirs,$ginc) if defined $ginc; push (@incDirs,"/usr/include"); } $incl = `cmt show macro_value use_includes`; chop $incl; if ($incl =~ /^\s*$/) { print &Warn("could not find any include directories from cmt command:\n cmt show macro_value use_includes\n"); } @incl = split(" ",$incl); foreach $i (@incl) { if ($i =~ /\-I(.*)/) { $ii = $1; $ii =~ s/\"//g; push (@incDirs,$ii); } } if ($list == 1) { print "Include directories for package $package:\n "; print join("\n ",@incDirs),"\n"; exit(0); } $r = 0; foreach $ifile (@files) { if ($#files > 0 && $quiet == 0) { print &Center("$ifile","-"),"\n"; } $r += &Check($ifile); } exit($r); ############################################################################# sub Check { my ($file) = @_ if @_; my ($ofile,$line,$n,$incf,$sysinc,$oline,$odef,$def,$change,@out,$i); if (!defined $ifile) { &Help(0); return 0; } if (!-f $ifile) { print &Error("file \"$ifile\" doesn't exist\n"); return 1; } $ofile = $ifile . ".def"; open(IN,$ifile); $change = 0; $n = 0; while() { $n++; $line = $_; if ($line =~ /^\s*\#\s*include/) { chop $line; ($incf = $line) =~ s/^\s*\#\s*include\s*//; if ($incf =~ /[\<\>]/) { $sysinc = 1; } else { $sysinc = 0; } &Debug("$n: $line"); if ($sysinc == 1 && $sys == 0) { $oline = $line; push (@out,"$line\n"); next; } $incf =~ s/\/\*.*\*\///g; $incf =~ s/\/\/.*$//g; $incf =~ s/[\"\<\>\'\s]//g; $incf =~ s/\/\/.*$//; ($def,$full) = &FindDefine($incf); if ($oline =~ /^\s*#\s*ifndef/) { ($odef = $oline) =~ s/^\s*\#\s*ifndef//; $odef =~ s/\s*//g; $odef =~ s/\/\*.*\*\///g; &Debug("defs: $def $odef\n"); if ($def != -1 && $def != -2) { if ($def ne $odef) { print "\n"; print &Error("line $n: include file \"$incf\" current \#define"); print "\n \"$odef\" and \#define found in "; print "header file\n $full"; print "\n \"$def\" do not match!\n\n"; $change = 1; foreach $i (reverse 0..$#out) { if ($out[$i] =~ /$odef/) { $out[$i] =~ s/$odef/$def/; break; } } } } elsif ($def == -2) { print "\n",&Error("line $n: no \#define found for $incf\n"); print " but file uses include guard \"$odef\"\n\n"; } else { print "\n",&Error("line $n: include file \"$incf\" not found\n"); print " but file uses include guard \"$odef\"\n\n"; } push(@out,"$line\n"); next; } $oline = $line; if ($def == -1) { print "\n",&Error("line $n: include file \"$incf\" was not found.\n\n"); push(@out,"$line\n"); } elsif ($def == -2) { print "\n",&Error("line $n: no \#define found for $incf\n\n"); push(@out,"$line\n"); } else { print "adding ",&Bold($def)," for $incf\n" if ($quiet != 1); push (@out,"\#ifndef $def\n"); push (@out," $line\n"); push (@out,"\#endif\n"); $change = 1; } } else { if ($line !~ /^\s*\n/) { $oline = $line; } push (@out,$line); } } close(IN); if ($change != 0) { if ($__DEBUG__) { &Debug("Debug mode: no output created\n"); return 0; } if (-f $ofile && $quiet != 1) { print &Warn("overwriting existing \"$ofile\"\n"); } open (OUT,">$ofile"); foreach (@out) { print OUT $_; } close (OUT); } else { print "No changes made to $ifile\n" if $quiet != 1; } return 0; } ############################################################################# sub FindDefine { my ($file) = @_ if @_; my ($i,$def,$ifndef,@def); foreach $i (@incDirs) { if (-f "$i/$file") { open(INCF,"$i/$file"); while() { if (/^\s*\#\s*ifndef/) { ($ifndef = $_ ) =~ s/^\s*\#\s*ifndef//; chop $ifndef; $ifndef =~ s/\s*//g; $ifndef =~ s/\/\*.*\*\///g; } elsif (/^\s*\#\s*define/) { ($def = $_ ) =~ s/^\s*\#\s*define//; chop $def; $def =~ s/\/\*.*\*\///g; @def = split(' ',$def); $def = $def[0]; $def =~ s/\s*//g; if ($def eq $ifndef) { close ($INCF); return ($def,"$i/$file"); } } } close($INCF); return (-2,"$i/$file"); } } return(-1,""); } ############################################################################# sub Help { my ($x) = @_; print &Usage("[-hlqs] FILE [FILE2 ...]"); if (defined $x && $x > 0) { print "\n Checks \#define include file protections\n\n"; print " Will create FILE.def with the correct \#ifndef statements\n"; print " and check to see if the one\'s you\'ve used are correct\n\n"; print " OPTIONS: \n"; print " h : this help\n"; print " l : list include directories\n"; print " q : quiet mode - only print errors\n"; print " s : check against system includes too\n"; } }