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=©ExternalIncludes ($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=©NewFiles();
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 }