diff options
Diffstat (limited to 'src/build/tools/addCopyright.pl')
-rwxr-xr-x | src/build/tools/addCopyright.pl | 622 |
1 files changed, 622 insertions, 0 deletions
diff --git a/src/build/tools/addCopyright.pl b/src/build/tools/addCopyright.pl new file mode 100755 index 000000000..f5fc3f4f1 --- /dev/null +++ b/src/build/tools/addCopyright.pl @@ -0,0 +1,622 @@ +#!/usr/bin/perl +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/tools/addCopyright.pl $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2011 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or other- +# wise divested of its trade secrets, irrespective of what has +# been deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END + +# Forked from: +# Author: Mark Jerde (mjerde@us.ibm.com) +# Date: Fri Mar 19 17:40:32 2010 UTC +# +# CVS Information: +# $Revision: 1.55 $ +# $Date: 2011/01/10 19:23:05 $ +# $RCSfile: addCopyright.pl,v $ + +use strict; +use warnings; + +#################################### ABOUT #################################### +# addCopyright.pl will automatically insert appropriate copyright statements # +# in source files following the IBM copyright guidelines (and templates) # +# referenced below : # +# FSP ClearCase Architecture # +# Version 1.9 # +# 10/12/2010 # +# Editor: Alan Hlava # +# # +# Section 3.14.1 has templates for different files # +# # +# NOTE: FSP uses the phrase "OCO Source materials" in their copyright # +# block, which is classified as 'p1' . We will use the same # +# classification here. # +# NOTE: to list all files in src EXCEPT the build dir, run: # +# make clean # remove autogenerated files # +# find src -path 'src/build' -prune -o ! -type d -print | tr '\n' ' ' # +# # +# addCopyright.pl does not support piping, but you can send these # +# to a file, add "addCopyright.pl update" to the beginning of the line, # +# and run the file to update all # +############################################################################### + +# Project-specific settings. +# +## my $releaseYear = "2011"; +my $releaseYear = `date +%Y`; +chomp( $releaseYear ); +my $copyrightSymbol = ""; +# my $copyrightSymbol = "(C)"; # Uncomment if unable to use character. + +my $projectName = "HostBoot"; +my $DELIMITER_END = "IBM_PROLOG_END"; +my $DELIMITER_BEGIN = "IBM_PROLOG_BEGIN_TAG"; +my $DELIMITER_WARNING_TEXT = "This is an automatically generated prolog."; +my $PVALUE = "p1"; ## my best guess + +my $PVALUE_TEXT = +"Object Code Only (OCO) source materials + Licensed Internal Code Source Materials + IBM $projectName Licensed Internal Code + + The source code for this program is not published or other- + wise divested of its trade secrets, irrespective of what has + been deposited with the U.S. Copyright Office."; +my $ORIGIN = "30"; + + +# End Project-specific settings + +####################################################################### +# Main +####################################################################### + +if (scalar(@ARGV) < 2) +{ + usage(); +} + +## +my $operation = shift; +if (not ($operation =~ m/update/i) and + not ($operation =~ m/validate/i)) +{ + print "Operation update or validate is required\n"; + usage(); +} + +## check for debug mode +my $debug = shift( @ARGV ); +# print "$debug\n"; +if ( $debug =~ m/debug/i ) +{ + print STDERR "debug mode\n"; + $debug = 1; +} +else +{ + print STDERR "normal mode\n"; + unshift( @ARGV , $debug ); + $debug = 0; +} + +# Read files and process. +while (defined($_ = shift)) +{ + my $filetype = filetype($_); + print "File $_: Type $filetype\n"; + + + + ## + ## validate + ## Exit 1 for unknown filetype + ## Exit 2 if has old copyright block + ## Exit 3 if no copyright block + ## + if ( $operation =~ m/validate/i ) + { + if ("Unknown" eq $filetype) + { + print "ERROR: File $_ :Unknown Filetype: $_"; + exit 1; + } + if ( hasoldcopyrightblock( $_, $filetype ) ) + { + print "ERROR File $_: has old copyright block, please fix\n"; + exit 2; + } + + if ( ! hascopyrightblock( $_, $filetype ) ) + { + print "ERROR File $_: Missing Copyright notice!!!\n"; + exit 3; + } + + # good file + next; + } + + ## + ## update + ## Continue with a warning for unknown filetype - + ## + if ($operation =~ m/update/i) + { + if ("Unknown" eq $filetype) + { + print "!!!!! WARNING: File $_ :Unknown Filetype: $_\n"; + next; + } + ## do a check for the old "$IBMCopyright: $" block + if ( hasoldcopyrightblock ( $_, $filetype ) ) + { + print "ERROR File $_: has old copyright block, please fix\n"; + exit 2; + } + + if ( ! hascopyrightblock( $_, $filetype ) ) + { + if ($debug) { print "Add empty copyright block\n"; } + addEmptyCopyrightBlock( $_, $filetype ); + ## check that the first part worked + if ( ! hascopyrightblock( $_, $filetype ) ) + { + print STDERR "Failed to create Copyright block, please fix\n"; + exit 2; + } + + fillInEmptyCopyrightBlock( $_, $filetype ); + } + } + +} # endwhile + + + +######################################################################### +## Subroutines +######################################################################### + +####################################### +## usage: print usage and quit +####################################### +sub usage +{ + print "Usage: addCopyright.pl { update | validate } [ debug ] file1 ...\n\n"; + exit 1; +} + +##################################### +## log unknown file type - unfinished +##################################### +sub logUnknownFiletype +{ + my $filename = shift; + my $fileinfo = shift; + + # TODO + print "Unknown filetype: $filename $fileinfo\n"; +} + +##################################### +## Analyze file and return a text string of the file type +##################################### +sub filetype +{ + my $filename = shift; + my $fileinfo = `file $filename | sed 's/^.*: //'`; + chomp $fileinfo; + + # Sorted by anticipated frequency of occurrence. + if ( ( $filename =~ m/\.[cht]$/i ) + ||( $filename =~ m/\.[cht]\+\+$/i ) + ||( $filename =~ m/\.[cht]pp$/i ) + ||( $fileinfo =~ m/c program text/i ) + ||( $fileinfo =~ m/c\+\+ program text/i ) + ) + { + return "C"; + } + if ( ( $filename =~ m/\.pl$/ ) + ||( $filename =~ m/\.perl$/ ) + ||( $filename =~ m/\.pm$/ ) + ||( $fileinfo =~ m/perl.*script text executable/i) ) + { + return "Perl"; + } + if ($filename =~ m/\.s$/i) + { + return "Assembly"; + } + if (($filename =~ m/Makefile$/i) or + ($filename =~ m/\.mk$/i)) + { + return "Makefile"; + } + if ( $filename =~ m/\.am$/i ) + { + return "Automake"; + } + if ( ($filename =~ m/configure\.ac$/i) + ||($filename =~ m/Makefile\.in$/i) ) + { + return "Autoconf"; + } + if ( ( $filename =~ m/\.[kc]{0,1}sh$/i ) + ||( $filename =~ m/\.bash$/i ) + ||( $fileinfo =~ m/shell script/i ) + ||( $fileinfo =~ m/^a \/bin\/[af]sh( -x|) *script text( executable|)$/ ) + ||( $fileinfo eq "Bourne shell script text") + ||( $fileinfo eq "Bourne shell script text executable") + ||( $fileinfo eq "Bourne-Again shell script text") + ||( $fileinfo eq "Bourne-Again shell script text executable") ) + { + return "Shellscript"; + } + if ( $filename =~ m/\.py$/ ) + { + return "Python"; + } + if ( $filename =~ m/\.tcl$/ ) + { + return "Tcl"; + } + if ( $filename =~ m/\.x$/ ) + { + return "RPC"; + } + if ( ($filename =~ m/^commitinfo$/) + ||($filename =~ m/^checkoutlist$/) + ||($filename =~ m/^loginfo$/) ) + { + return "CVS"; + } + if ( $filename =~ m/\.emx$/ ) + { + # Used by Rational Software Architect. modelling file. + return "EmxFile"; + } + if ( $filename =~ m/\.mof$/ ) + { + return "MofFile"; + } + if ( $filename =~ m/\.ld$/ ) + { + return "LinkerScript"; + } + if ( $filename =~ m/\.xml$/i ) + { + return "xml" + } + if ( ( $filename =~ m/\.emx$/i ) + ||( $filename =~ m/\.odt$/i ) + ||( $filename =~ m/\.gitignore$/i ) + ||( $filename =~ m/\.conf$/i ) + ||( $filename =~ m/\.lidhdr$/i ) + ||( $filename =~ m/\.vpdinfo$/i ) + ||( $filename =~ m/\.pdf$/i ) + + ) + { + # Known, but we can't deal with it so call it unknown. + return "Unknown"; + } + if ( -f $filename ) + { + my $type = `grep "\\\$Filetype:.*\\\$" $filename`; + if ( $type =~ m/\$Filetype:([^\$]*)\$/ ) + { + $type = $1; + } + $type =~ s/^\s*//; + $type =~ s/\s*$//; + my %knownTypes = qw/Assembly Assembly Automake Automake Autoconf Autoconf C C CVS CVS EmxFile EmxFile LinkerScript LinkerScript Makefile Makefile MofFile MofFile Perl Perl Python Python RPC RPC Shellscript Shellscript Tcl Tcl/; + return $type if defined($knownTypes{$type}); + } + { # Other random files containing non-printable characters. + my $file = `cat $filename`; + if ( $file =~ m/([^\x20-\x7E\s])/ ) + { + return "Unknown"; + } + } + logUnknownFiletype($filename,$fileinfo); + return "Unknown"; +} + +###################################### +## Figure out the first copyright year for the file +## return as a string +###################################### +sub copyrightFirstYearForFile +{ + my $file = shift; + my $fileContent = shift; + my $year = $releaseYear; + my @logstrings; + # TODO find multiple copyright statements and pick the earliest one + # Search for earlier years from prior release. + if ($fileContent =~ m/Copyright IBM Corp. (\d{4})/) + { + $year = $1 if ($1 < $year); + } + + my $cmd = "git log -- $file | grep Date: | tail --line=1"; + ## print "run $cmd\n"; + @logstrings = split( " ", `$cmd` ); + + # new files will not have a log, so the "git log" call above will + # return nothing. In this case, just return the old calculated + # value. + if ( (scalar(@logstrings) < 5) or ($year lt $logstrings[5]) ) + { + return $year; + } + else + { + return $logstrings[5]; + } +} + +######################################## +## Figure out the last copyright year for file +## Return as a string +######################################## +sub copyrightLastYearForFile +{ + return $releaseYear; +} + + + +####################################### +## Check for old $IBMCopyrightBlock signature +## return 1 if it's there, otherwise 0 +####################################### +sub hasoldcopyrightblock +{ + my ( $filename, $filetype ) = @_; + my $file = `head -180 $filename`; # Must appear in first 180 lines. + + if ( $file =~ m/\$IBMCopyrightBlock:.*\$/s ) + { + return 1; + } + + return 0; +} + +####################################### +## Check for new IBM_PROLOG_BEGIN_TAG signature +## return 1 if it's there, otherwise 0 +####################################### +sub hascopyrightblock +{ + my ( $filename, $filetype ) = @_; + my $file = `head -180 $filename`; # Must appear in first 180 lines. + + #print $filename; + #print $file; + #print $DELIMITER_BEGIN; + #print $DELIMITER_END; + + + if ( $file =~ m/$DELIMITER_BEGIN.*$DELIMITER_END/s ) + { + return 1; + } + + return 0; +} +################################### +## Add an empty copyright block to the file, for example (C/C++ files): +## +## // IBM_PROLOG_BEGIN_TAG IBM_PROLOG_END_TAG +## +## - The block will be filled-in in the next step. +## - Makes up a temporary file called "<filename>.cvsCPYRT" +################################## +sub addEmptyCopyrightBlock +{ + my ( $filename, $filetype) = @_; + my $line; + open(INPUT, $_) or exit; + system "touch $_.cvsCPYRT"; + open(OUTPUT, ">$_.cvsCPYRT") or exit; + + if ("Assembly" eq $filetype) + { + ## print OUTPUT ";// \$IBMCopyrightBlock: \$\n"; + print OUTPUT "# $DELIMITER_BEGIN $DELIMITER_END\n"; + } + elsif (("Autoconf" eq $filetype) or + ("Automake" eq $filetype) or + ("CVS" eq $filetype) or + ("Makefile" eq $filetype) or + ("Perl" eq $filetype) or + ("Python" eq $filetype) or + ("Shellscript" eq $filetype) or + ("Tcl" eq $filetype)) + { + $line = <INPUT>; + # Keep the '#!' line at the top. + if ($line =~ m/^#!/) + { + print OUTPUT $line; + } + ## print OUTPUT "# \$IBMCopyrightBlock: \$\n"; + print OUTPUT "# $DELIMITER_BEGIN $DELIMITER_END\n"; + unless ($line =~ m/^#!/) + { + print OUTPUT $line; + } + } + elsif ( ("C" eq $filetype) + ) + { + ##print OUTPUT " * \$IBMCopyrightBlock: \$\n"; + print OUTPUT "// $DELIMITER_BEGIN $DELIMITER_END\n"; + } + elsif ( ("RPC" eq $filetype) or + ("LinkerScript" eq $filetype) + ) + { + # ld stubbornly refuses to use modern comment lines. + print OUTPUT "/* $DELIMITER_BEGIN $DELIMITER_END\n */\n"; + } + elsif ("MofFile" eq $filetype) + { + ##print OUTPUT "// \$IBMCopyrightBlock: \$\n"; + print OUTPUT "// $DELIMITER_BEGIN $DELIMITER_END\n"; + } + elsif ("xml" eq $filetype ) + { + print OUTPUT "<!-- $DELIMITER_BEGIN $DELIMITER_END -->\n"; + } + else + { + print STDERR "Can\'t handle filetype: $filetype\n"; + exit 1; + } + + # Copy rest of file + while (defined($line = <INPUT>)) + { + print OUTPUT $line; + } + close OUTPUT; + close INPUT; + system "cat $_.cvsCPYRT > $_"; + system "rm -f $_.cvsCPYRT"; + system "touch $_"; + +} + +############################################ +## fill in the empty copyright block +## Copyright guidelines from: +## FSP ClearCase Architecture +## Version 1.9 +## 10/12/2010 +## Editor: Alan Hlava +## +## Section 3.14.1 has templates for different files +## +############################################ +sub fillInEmptyCopyrightBlock +{ + my ( $filename, $filetype ) = @_; + my $file = `cat $_`; + my $firstYear = copyrightFirstYearForFile($_, $file); + my $lastYear = copyrightLastYearForFile($_); + my $copyrightYear = $firstYear; + $copyrightYear .= " - $lastYear" unless ( "$firstYear" eq "$lastYear" ); + ## define the final copyright block template here. + my $IBMCopyrightBlock = +" $DELIMITER_BEGIN + $DELIMITER_WARNING_TEXT + + \$Source: $filename \$ + + IBM CONFIDENTIAL + + COPYRIGHT International Business Machines Corp. $copyrightYear + + $PVALUE + + $PVALUE_TEXT + + Origin: $ORIGIN + + $DELIMITER_END"; + + + if (($file =~ m/$DELIMITER_BEGIN*.$DELIMITER_END/s ) and + ("Unknown" ne $filetype)) + { + open(INPUT, $_ ) or exit; + system "touch $_.cvsCPYRT"; + open(OUTPUT, ">$_.cvsCPYRT") or exit; + + my $newline; + my $lines = ""; + while ( defined($newline = <INPUT>) ) { $lines .= $newline; } + + if ("Assembly" eq $filetype) + { + ## assembly + $IBMCopyrightBlock =~ s/\n/\n# /sg; + } + if (("Autoconf" eq $filetype) or + ("Automake" eq $filetype) or + ("CVS" eq $filetype) or + ("Makefile" eq $filetype) or + ("Perl" eq $filetype) or + ("Python" eq $filetype) or + ("Shellscript" eq $filetype) or + ("Tcl" eq $filetype)) + { + $IBMCopyrightBlock =~ s/\n/\n#/sg; + } + if (("C" eq $filetype) + ) + { + # Use C++ style comments + $IBMCopyrightBlock =~ s|\n|\n//|sg; + } + if (("RPC" eq $filetype) or + ("LinkerScript" eq $filetype) + ) + { + $IBMCopyrightBlock =~ s|\n|\n *|sg; + } + if ("EmxFile" eq $filetype) + { + # Not yet formatted correctly for EmxFile needs, but should coexist. + $IBMCopyrightBlock = "$DELIMITER_BEGIN IBM Confidential OCO Source Materials (C) Copyright IBM Corp. $copyrightYear The source code for this program is not published or otherwise divested of its trade secrets, irrespective of what has been deposited with the U.S. Copyright Office. $DELIMITER_END"; + } + if ("MofFile" eq $filetype) + { + $IBMCopyrightBlock =~ s|\n|\n//|sg; + } + if ( "xml" eq $filetype) + { + $IBMCopyrightBlock =~ s|\n|\n |sg; + } + + # Replace existing block with the current content. + # $lines =~ s/\$IBMCopyrightBlock:[^\$]*\$/$IBMCopyrightBlock/s; + $lines =~ s/$DELIMITER_BEGIN[^\$]*$DELIMITER_END/$IBMCopyrightBlock/s; + + print OUTPUT $lines; + close OUTPUT; + close INPUT; + + system "cat $_.cvsCPYRT > $_"; + system "rm -f $_.cvsCPYRT"; + system "touch $_"; + } + else + { + print "Cannot find empty copyright block\n"; + exit 1; + } +} |