Back to home page

Project CMSSW displayed by LXR

 
 

    


Warning, /Utilities/ReleaseScripts/scripts/chkincludes is written in an unsupported language. File is not indexed.

0001 #!/usr/bin/env perl
0002 use Cwd;
0003 use File::Basename;
0004 use lib dirname($0);
0005 use Getopt::Long;
0006 use SCRAMGenUtils;
0007 $|=1;
0008 
0009 #Getopt::Long::config qw(default no_ignore_case require_order);
0010 if(&GetOptions(
0011                "--pack=s",\$package,
0012                "--clean",\$clean,
0013                "--vclean",\$vclean,
0014                "--detail",\$detail,
0015                "--update",\$localupdate,
0016                "--headers",\$headers,
0017                "--help",\$help,
0018               ) eq ""){print "ERROR: Wrong arguments.\n"; &usage_msg(); exit 1;}
0019 
0020 if (defined $help){&help_msg(0);}
0021 if(defined $clean){$clean=1;}
0022 else{$clean=0;}
0023 if (defined $vclean){$clean=2;}
0024 if (defined $localupdate){$localupdate=1;}
0025 else{$localupdate=0;}
0026 if (defined $detail){$detail=1;}
0027 else{$detail=0;}
0028 if (defined $headers){$headers="";}
0029 else{$headers="--skipheaders";}
0030 if((!defined $package) || ($package=~/^\s*$/)){$package="";}
0031 
0032 my $curdir=cwd();
0033 my $scriptdir=dirname($0);
0034 my $xincargs="";
0035 while(my $arg=shift)
0036 {
0037   if($arg=~/\s/){$arg="\"$arg\"";}
0038   #$xincargs.=" $arg";
0039 }
0040 
0041 my $localtop = &SCRAMGenUtils::scramReleaseTop($curdir);
0042 if($localtop eq ""){die "\"$curdir\" is not a SCRAM-based project area. Please create a SCRAM-based project dev area and run this script";}
0043 my $releasetop=&SCRAMGenUtils::getFromEnvironmentFile("RELEASETOP","$localtop") || $localtop;
0044 if($releasetop eq $localtop){die "\"$localtop\" is a release area. Please run this script in your developer area.\n";}
0045 &SCRAMGenUtils::init($localtop);
0046 
0047 my $arch=&SCRAMGenUtils::getScramArch();
0048 my $tmpdir="${localtop}/tmp/IncludeChecker/${arch}";
0049 my $src=&SCRAMGenUtils::getFromEnvironmentFile("SCRAM_SOURCEDIR",$localtop) || "src";
0050 
0051 $package=~s/^\s*//;$package=~s/\s*$//;
0052 if($package eq ""){$package=$src;}
0053 if($clean)
0054 {
0055   my $msg=0;
0056   foreach my $file (`find ${tmpdir}/inccopy/self -name "*.original_file_wo_incchk_changes" -type f`)
0057   {
0058     chomp $file;
0059     $file=~s/\.original_file_wo_incchk_changes//;
0060     my $rf=$file; $rf=~s/^${tmpdir}\/inccopy\/self\/inc\d+\///;
0061     if(!$msg){print "Copying original files back to ${localtop}/${src}:\n";$msg=1;}
0062     print "  $rf\n";
0063     system("mv ${file}.original_file_wo_incchk_changes $file; cp -f $file ${localtop}/src/${rf}");
0064   }
0065   if (-d $tmpdir)
0066   {
0067     if($clean>1){system("rm -rf $tmpdir");}
0068     else{foreach my $d (&SCRAMGenUtils::readDir($tmpdir)){if($d!~/^(inccopy|backup)$/){system("rm -rf ${tmpdir}/${d}");}}}
0069   }
0070   exit 0;
0071 }
0072 if (!-d $package){$package="${src}/${package}";}
0073 if(-d $package)
0074 {
0075   my $d=$package;
0076   if($d!~/^\//){$d="${curdir}/${package}";}
0077   $d=&SCRAMGenUtils::fixPath($d);
0078   if($d=~/^$localtop\/(${src}\/*.*)$/){$package=$1;}
0079   else{$package="";}
0080 }
0081 if($package eq ""){die "Please use a valid Subsystem/Package name.\n  Usage: $0 <Subsystem/Package|clean>";}
0082 if(!-d "${localtop}/${package}")
0083 {die "There is no such subsystem/package/directory \"$package\" available under \"${localtop}\". Please first checkout this package.";}
0084 my $scram=$SCRAMGenUtils::SCRAM_CMD;
0085 system("mkdir -p ${tmpdir}/config ${tmpdir}/log;$scram b -r echo_CXX ufast >/dev/null 2>&1");
0086 my $localbackup="${tmpdir}/inccopy/self/inc0";
0087 my $incmap=&copyExternalIncludes ($arch,$localtop,"${tmpdir}/inccopy");
0088 
0089 print ">> IncludeChecker temporary directory: ${tmpdir}\n";
0090 
0091 my $cache={};
0092 my $cfile="${tmpdir}/cache/files.info";
0093 if(-f $cfile){$cache=&SCRAMGenUtils::readHashCache($cfile);}
0094 &processPack ($package,$cache);
0095 if(-d "${tmpdir}/cache"){&SCRAMGenUtils::writeHashCache($cache,$cfile);}
0096 if ($localupdate && (-d "${tmpdir}/includechecker/${src}"))
0097 {
0098   my $msg=0;
0099   foreach my $f (`find ${tmpdir}/includechecker/${src} -name "*.backup_new" -type f`)
0100   {
0101     chomp $f;
0102     my $rf=$f; $rf=~s/\.backup_new$//;$rf=~s/^${tmpdir}\/includechecker\/src\///;
0103     if(!$msg){print "Cleaning up Include Checker comments from ${localtop}/${src}:\n";$msg=1;}
0104     print "  ${rf}\n";
0105     system("mv ${f} ${localtop}/${src}/${rf}");
0106     if (-f "${localbackup}/${rf}"){system("cp -pf ${localtop}/${src}/${rf} ${localbackup}/${rf}");}
0107   }
0108 }
0109 system("rm -f ${tmp_dir}/chkquit");
0110 exit 0;
0111 
0112 sub processPack ()
0113 {
0114   if (-f "${tmp_dir}/chkquit"){return;}
0115   my $package=shift;
0116   my $cache=shift;
0117   my $uniqpack=$package; $uniqpack=~s/\///g;
0118   my $configfile="${tmpdir}/config/${uniqpack}";
0119   print "################# $package #############################\n";
0120   print ">> IncludeChecker log file           : ${tmpdir}/log/${uniqpack}\n";
0121   print ">> IncludeChecker config file        : ${tmpdir}/config/${uniqpack}\n";
0122   my $cont=0;
0123   if(-f "${tmpdir}/log/${uniqpack}")
0124   {
0125     my $c=0;
0126     while(-f "${tmpdir}/log/${uniqpack}.${c}"){$c++;}
0127     system("mv ${tmpdir}/log/${uniqpack} ${tmpdir}/log/${uniqpack}.${c}");
0128     $cont=1;
0129   }
0130   if((-f "${tmpdir}/cache/config_cache") && ($cont==0)){system("touch ${tmpdir}/cache/config_cache.append");}
0131   else{system("rm -f ${tmpdir}/cache/config_cache.append");}
0132   if(!-f $configfile)
0133   {
0134     print ">> Running \"${scriptdir}/createconfig.pl ${localtop}/${package}\"\n";
0135     system("${scriptdir}/createconfig.pl ${localtop}/${package} > ${configfile}.tmp && mv ${configfile}.tmp $configfile");
0136     if(-f "extra_includechecker.conf"){system("cat extra_includechecker.conf >> $configfile");}
0137     &updateMapping($configfile,$incmap);
0138   }
0139   print ">> Waiting for copy process to finish .... ";
0140   &SCRAMGenUtils::waitForChild ();
0141   print "[ DONE ]\n";
0142   print ">> Running \"includechecker.pl --config $configfile --tmpdir $tmpdir --keep --detail --recursive --local $headers $xincargs\"\n";
0143   print ">> Log file for the includechecker.pl processing: ${tmpdir}/log/${uniqpack}\n";
0144   system("${scriptdir}/includechecker.pl --config $configfile --tmpdir $tmpdir --keep --detail --recursive --local $headers $xincargs 2>&1 > ${tmpdir}/log/${uniqpack}");
0145   print ">> Done: includechecker.pl\n";
0146   if(-f "${tmp_dir}/chkquit"){return;}
0147   &processResult($cache);
0148   my $deps={};
0149   $deps=&copyNewFiles();
0150   foreach my $pack (keys %$deps)
0151   {
0152     my $packx=$pack; $packx=~s/\///;
0153     if(!-f "${tmpdir}/config/${packx}"){&processPack("${src}/${pack}",$cache);}
0154   }
0155 }
0156 
0157 sub processResult ()
0158 {
0159   my $cache=shift;
0160   my $newfiles = &getNewFiles("${tmpdir}/cache/files");
0161   my $done=[];
0162   my $failed=[];
0163   my $skipped=[];
0164   my $total=0;
0165   foreach my $f (@$newfiles)
0166   {
0167     if(-f $f)
0168     {
0169       my $rf=$f; $rf=~s/^${tmpdir}\/cache\/files\///;
0170       if(exists $cache->{read}{$rf}){next;}
0171       $cache->{read}{$rf}=1;
0172       $total++;
0173       my $ref=&SCRAMGenUtils::readHashCache($f);
0174       if ((exists $ref->{ERROR}) && ($ref->{ERROR}==1)){push @$failed,$rf;next;}
0175       if ((exists $ref->{FINAL_DONE}) && ($ref->{FINAL_DONE}==1)){push @$done,$rf;next;}
0176       if ((exists $ref->{INTERNAL_SKIP}) && ($ref->{INTERNAL_SKIP}==1)){push @$skipped,$rf;next;}
0177     }
0178   }
0179   print "Total files checked:           $total\n";
0180   print "  Failed due to compilation:   ",scalar(@$failed),"\n";
0181   foreach my $f (@$failed){print "    $f\n";}
0182   print "  Skipped:                     ",scalar(@$skipped),"\n";
0183   if($detail){foreach my $f (@$skipped){print "    $f\n";}}
0184   print "  Successfully processed:      ",scalar(@$done),"\n";
0185 }
0186 
0187 sub copyNewFiles ()
0188 {
0189   my $newdeps={};
0190   my $newfiles = &getNewFiles("${tmpdir}/includechecker");
0191   my $modfile=scalar(@$newfiles);
0192   my $doscramb=0;
0193   foreach my $f (@$newfiles)
0194   {
0195     my $rf=$f; $rf=~s/^${tmpdir}\/includechecker\/${src}\///;
0196     my $pack=$rf; $pack=~s/^([^\/]+?\/[^\/]+?)\/.+/$1/;
0197     if(!-d "${localtop}/${src}/${pack}")
0198     {
0199       if(-d "${releasetop}/${src}/${pack}")
0200       {
0201         my $subsys=dirname("${localtop}/${src}/${pack}");
0202         system("mkdir -p $subsys; cp -r ${releasetop}/${src}/${pack} $subsys");
0203         $doscramb=1;
0204         $newdeps->{$pack}=1;
0205       }
0206     }
0207     my $oref; my $iref;
0208     my $added=0; my $removed=0;
0209     open($iref,$f) || die "Can not open file \"$f\" for reading.";
0210     open($oref,">$f.backup_new") || die "Can not open file \"$f.backup_new\" for writing.";
0211     while(my $line=<$iref>)
0212     {
0213       chomp $line;
0214       if($line=~/^\s*\/\/INCLUDECHECKER: Removed this line:/){$removed++;next;}
0215       elsif($line=~/(.*?)\/\/INCLUDECHECKER: Added this line\s*$/){$added++;$line=$1;}
0216       print $oref "$line\n";
0217     }
0218     close($oref); close($iref);
0219     if ($removed || $added)
0220     {
0221       system("mv $f $f.modified_by_incchk");
0222       print "    $rf ($removed,$added)\n";
0223     }
0224     else{system("rm -f $f.backup_new $f");$modfile--;}
0225   }
0226   if($modfile == 0){print "It seemed that file(s) processed successfully by includechecker are all good. No include statement added/removed.\n";}
0227   else{print "  Modified by includechecker:  $modfile\n";}
0228   if($doscramb){system("cd $localtop; $scram b -r echo_CXX 2>&1 > /dev/null");}
0229   return $newdeps;
0230 }
0231 
0232 sub getNewFiles ()
0233 {
0234   my $dir=shift;
0235   my $files=shift || [];
0236   foreach my $d (&SCRAMGenUtils::readDir($dir))
0237   {
0238     my $fullpath="${dir}/${d}";
0239     if(-d $fullpath){&getNewFiles($fullpath,$files);}
0240     elsif(-f $fullpath)
0241     {
0242       if($fullpath=~/(.*?)\.(backup_new|modified_by_incchk)$/){next;}
0243       push @$files,$fullpath;
0244     }
0245   }
0246   return $files;
0247 }
0248 
0249 sub copyExternalIncludes ()
0250 {
0251   my $arch=shift;
0252   my $release=shift;
0253   my $des=shift;
0254   my $map=shift || {};
0255 
0256   my %incdir=();
0257   my %cache=();
0258   if (!-f "${des}/mapping.txt")
0259   {print "MSG: Copying all the external includes files under ${des} directory. This might take few mins.\n";}
0260   $cache{toolcache}=&SCRAMGenUtils::readCache(&SCRAMGenUtils::fixCacheFileName("${release}/.SCRAM/${arch}/ToolCache.db"));
0261 
0262   if(exists $cache{toolcache}{SETUP})
0263   {
0264     foreach my $t (keys %{$cache{toolcache}{SETUP}})
0265     {
0266       if(exists $cache{toolcache}{SETUP}{$t}{INCLUDE})
0267       {
0268         my $c=0;
0269         foreach my $d (@{$cache{toolcache}{SETUP}{$t}{INCLUDE}})
0270         {
0271           if(-d $d)
0272           {
0273             my $inc="inc$c";
0274             $incdir{$d}{$t}="$inc";
0275             $c++;
0276             if (($t eq "self") && ($d eq "${release}/${src}"))
0277             {
0278               $localbackup="${des}/${t}/${inc}";
0279               &syncDirs("${release}/${src}",$localbackup);
0280             }
0281           }
0282         }
0283       }
0284     }
0285   }
0286 
0287   my %udir=();
0288   foreach my $d (sort keys %incdir)
0289   {
0290     my $link="";
0291     foreach my $ud (keys %udir)
0292     {
0293       my $xud=quotemeta($ud);
0294       if ($d=~/^$xud(\/.*|)$/)
0295       {
0296         $link=$udir{$ud};
0297         last;
0298       }
0299     }
0300     foreach my $t (keys %{$incdir{$d}})
0301     {
0302       my $inc=$incdir{$d}{$t};
0303       my $xd=quotemeta($d);
0304       $map->{$xd}="${des}/${t}/${inc}";
0305       if(!-e "${des}/${t}/${inc}")
0306       {
0307         system("mkdir -p ${des}/${t}");
0308         if(!$link)
0309         {
0310           if($detail){print "  Copying: $d -> ${des}/${t}/${inc}\n";}
0311           my $pid=&SCRAMGenUtils::forkProcess(10);
0312           if ($pid==0){system("cp -rL $d ${des}/${t}/${inc}"); exit 0;}
0313           $link="../${t}/${inc}";
0314         }
0315         else{system("cd ${des}/${t}; ln -s ${link} $inc");}
0316       }
0317       elsif($link eq ""){$link="../${t}/${inc}";}
0318     }
0319     $udir{$d}=$link;
0320   }
0321   &SCRAMGenUtils::writeHashCache($map,"${des}/mapping.txt");
0322   return $map;
0323 }
0324 
0325 sub updateMapping ()
0326 {
0327   my $file=shift;
0328   my $map=shift;
0329   my $refi;my $refo;
0330   open($refi,$file) || die "Can not open file for reading: $file\n";
0331   open($refo,">${file}.new") || die "Can not open file for writing: ${file}.new\n";
0332   while(my $line=<$refi>)
0333   {
0334     chomp $line;
0335     foreach my $xd (keys %{$map})
0336     {
0337       while($line=~/^(.*)$xd(\/.*|\s.*|)$/)
0338       {
0339         my $d=$map->{$xd};
0340         $line="$1$d$2";
0341       }
0342     }
0343     print $refo "$line\n";
0344   }
0345   close($refi); close($refo);
0346   system("mv ${file}.new $file");
0347 }
0348 
0349 sub syncDirs ()
0350 {
0351   my $src=shift;
0352   my $des=shift;
0353   my $dref;
0354   opendir($dref,$src) || die "Can not open directory for reading: $src";
0355   if (!-d $des){system("mkdir -p $des");}
0356   foreach my $p (readdir($dref))
0357   {
0358     if (($p eq ".") || ($p eq "..")){next;}
0359     my $srcp="${src}/${p}";
0360     my $desp="${des}/${p}";
0361     if (-d $srcp){&syncDirs($srcp,$desp);}
0362     elsif(!-e $desp){system("cp -p $srcp $desp");}
0363   }
0364   closedir($dref);
0365 }
0366 
0367 sub usage_msg ()
0368 {
0369   my $f=basename($0);
0370   print "\nUsage: $f [--pack <pack>] [--update] [--clean] [--vclean] [--detail] [--help] [--headers]\n\n";
0371 }
0372 
0373 sub help_msg ()
0374 {
0375   &usage_msg ();
0376   print " --pack <pack>\n",
0377         "          <pack> could have following values:\n",
0378         "            <subsystem> e.g. FWCore or src/FWCore.\n",
0379         "            <package>  e.g FWCore/Framework OR src/FWCore/Framework.\n",
0380         "            By default it runs for all sub-system(s) available under\n",
0381         "            your src directory.\n",
0382         " --clean  To cleanup preveious modifications made by include checker.\n",
0383         " --vclean Same as clean but it also deletes the copy of external includes.\n",
0384         " --update To remove the include checker comments from the modified files\n",
0385         "          in your src directory.\n",
0386         " --headers Force to check c/c++ header files too.\n";
0387         " --detail For detail output messages.\n";
0388         " --help   To print this help message.\n\n";
0389   print "It is a wrapper script to run includechecker. It automatically creates\n",
0390         "configuration and runs inlcudechecker. It can also clean the newly\n",
0391         "modified files (--update) by removing the include checker comments.\n",
0392         "NOTE: You need to run this from a user developer area.\n";
0393   exit shift;
0394 }