our $NEWFILES="$CLSCANDIR/new.txt";
our $COPYRIGHTSTUB="$CLSCANDIR/copyright.in";
-# FIXME: add boilerplate
-our %module_licenses= (
- "public domain" => "",
- "unlimited" =>
- "This file is free software; the Free Software Foundation\n" .
- "gives unlimited permission to copy and/or distribute it,\n" .
- "with or without modifications, as long as this notice is preserved.\n",
- "LGPL" => "",
- "LGPLv2+" => "",
- "unmodifiable license text" =>
- "Everyone is permitted to copy and distribute verbatim copies\n" .
- "of this license document, but changing it is not allowed.\n",
- "GPLed build tool" => "",
- "GPL" => "",
-);
+my $gpl_boilerplate=<<"EOL";
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+EOL
+
+my $lgpl2_boilerplate=<<"EOL";
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+ .
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+EOL
+
+my $lgpl3_boilerplate=<<"EOL";
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+EOL
+
+# license overrides as specified in modules/*
+our $module_licenses = {
+ "public domain" => {
+ license => "PD",
+ license_text => "",
+ },
+ "unlimited" => {
+ license => "other",
+ license_text => "This file is free software; the Free Software Foundation\n" .
+ "gives unlimited permission to copy and/or distribute it,\n" .
+ "with or without modifications, as long as this notice is preserved.\n",
+ },
+ "LGPL" => {
+ license => "LGPL",
+ license_text => $lgpl3_boilerplate,
+ },
+ "LGPLv2+" => {
+ license => "LGPL-2+",
+ license_text => $lgpl2_boilerplate,
+ },
+ "LGPLv3+" => {
+ license => "LGPL-3+",
+ license_text => $lgpl3_boilerplate,
+ },
+ "unmodifiable license text" => {
+ license => "other",
+ license_text => "Everyone is permitted to copy and distribute verbatim copies\n" .
+ "of this license document, but changing it is not allowed.\n",
+ },
+ "GPLed build tool" => {
+ license => "GPL",
+ license_text => $gpl_boilerplate,
+ },
+ "GPL" => {
+ license => "GPL",
+ license_text => $gpl_boilerplate,
+ },
+};
our @filenames=();
our %overrides=();
our $files={};
our $new={};
+our @deleted_files=();
+# actions
my $scan=0;
my $merge=0;
+my $help=0;
my $writecopyright=0;
usage() unless(@ARGV);
-usage() unless GetOptions("scan|s" => \$scan,
+usage() unless GetOptions("scan|s" => \$scan,
"merge|m" => \$merge,
"write|w" => \$writecopyright,
- "help|h" => sub { usage(); });
+ "help|h" => \$help);
+usage() if $help;
load_cache();
scan() if($scan);
merge() if($merge);
write_copyright() if ($merge || $writecopyright);
+
sub scan
{
get_filenames();
{
scan_file($file);
}
- write_new();
find_deleted();
+ write_new();
}
sub merge
my $licenses={};
for my $file (sort keys(%$files))
{
- my $license=$files->{$file}->{license};
+ my $license=$files->{$file}->{license_override} || $files->{$file}->{license};
my $copyright=$files->{$file}->{copyright};
- my $license_text=$files->{$file}->{license_text};
+ my $license_text=$files->{$file}->{license_text_override} ||
+ $files->{$file}->{license_text};
push(@{$licenses->{$license}->{$license_text}->{$copyright}}, $file);
}
my %refs=();
my $refnum="00";
+ print COPYRIGHT license_trailer(sort keys(%$licenses));
for my $license (sort keys(%$licenses))
{
for my $license_text (sort keys(%{$licenses->{$license}}))
$licensestr .= " [REF$refnum]";
$refs{$licensestr}=$license_text;
}
+ else
+ {
+ if(!length($license)) {
+ $licensestr="unknown";
+ }
+ }
for my $copyright (sort keys(%{$licenses->{$license}->{$license_text}}))
{
next if(!length($license) && !length($copyright) && !length($license_text));
my @filelist=sort @{$licenses->{$license}->{$license_text}->{$copyright}};
- print COPYRIGHT "Files: ", join(', ', @filelist), "\n";
- print COPYRIGHT "Copyright: $copyright\n" if length($copyright);
+ print COPYRIGHT "Files: ", join(' ', @filelist), "\n";
+ print COPYRIGHT "Copyright: ". (length($copyright) ? $copyright : "unknown" ) . "\n";
print COPYRIGHT "License: $licensestr\n" if length($licensestr);
print COPYRIGHT "\n";
}
}
}
- for my $ref (sort keys(%refs))
+ for my $ref (sort byref keys(%refs))
{
print COPYRIGHT "License: $ref\n";
my @text=split(/\n/, $refs{$ref});
+ @text=map { ($_ eq "") ? "." : $_; } @text;
print COPYRIGHT map { " " . $_ . "\n" } @text;
print COPYRIGHT "\n";
}
- print COPYRIGHT license_trailer(sort keys(%$licenses));
close(COPYRIGHT);
}
+sub byref
+{
+ my $aref=($a=~/\[REF(\d+)\]/)[0];
+ my $bref=($b=~/\[REF(\d+)\]/)[0];
+ if($aref && $bref)
+ {
+ return($aref <=> $bref);
+ }
+ return($a cmp $b);
+}
+
sub license_trailer
{
my @licenses_used=@_;
};
my %types_found=();
-TYPE: for my $type (reverse sort keys(%$license_data))
+ for my $type (reverse sort keys(%$license_data))
{
for my $license (@licenses_used)
{
- if($license =~ /$type(\+|\b)/i)
+ if($license =~ /$type(\+|\s|$)/i)
{
$types_found{$type}=1;
- # avoid matching eg GPL-2 *and* GPL
- next TYPE;
}
}
}
- my $text="\n";
+ my $text=" .\n";
# if just one, use standard style
if(keys(%types_found) == 1)
{
my ($file, $name)=each(%types_found);
- $text .= "The complete text of the $name can be\n";
- $text .= "found in /usr/share/common-licenses/$file\n";
+ $text .= " The complete text of the $name can be\n";
+ $text .= " found in /usr/share/common-licenses/$file\n";
}
else
{
# more than one, use table.
- $text .= "The complete text of standard licenses referenced above\n";
- $text .= "can be found in /usr/share/common-licenses/ as follows:\n\n";
- $text .= sprintf("%-70s %s\n", "LICENSE", "FILE");
+ $text .= " The complete text of standard licenses referenced above\n";
+ $text .= " can be found in /usr/share/common-licenses/ as follows:\n .\n ";
+ $text .= sprintf("%-60s %s\n", "LICENSE", "FILE");
for my $type (sort keys(%types_found))
{
- $text .= sprintf("%-70s %s\n", $license_data->{$type}, $type);
+ $text .= sprintf(" %-60s %s\n", $license_data->{$type}, $type);
}
}
+ $text .= "\n\n";
return $text;
}
{
if(exists($files->{$filename}->{copyright}))
{
- $new->{$filename}->{copyright_old}=$files->{$filename}->{copyright};
+ $new->{$filename}->{copyright}=$files->{$filename}->{copyright};
+ $new->{$filename}->{copyright_guess}=$copyright_guess;
}
if(exists($files->{$filename}->{license}))
{
- $new->{$filename}->{license_old}=$files->{$filename}->{license};
+ $new->{$filename}->{license}=$files->{$filename}->{license};
+ $new->{$filename}->{license_guess}=$license_guess;
}
if(exists($files->{$filename}->{license_text}))
{
- $new->{$filename}->{license_text_old}=$files->{$filename}->{license_text};
+ $new->{$filename}->{license_text}=$files->{$filename}->{license_text};
}
}
}
sub wanted_files
{
- if(/^\.git/ || /^\.cvs/ || /^debian/ || /^modules$/)
+ if(/^\.git/ || /^\.cvs/ || /^debian/ || /^modules$/ || /^\.pc/)
{
$File::Find::prune=1;
}
find({ wanted => \&wanted_modules, no_chdir => 1}, "modules/");
for my $license (keys(%overrides))
{
- print("License: $license\n");
- print("Files: \n\t");
- print(join("\n\t", @{$overrides{$license}}),"\n");
+ if(!exists($module_licenses->{$license}))
+ {
+ die("$me: license override \"$license\" not found in \$module_licenses\n");
+ }
+ my @overridden_files=map { "./" . $_; } @{$overrides{$license}};
+ for my $file (@overridden_files)
+ {
+ my $override=$module_licenses->{$license};
+ if(length($override->{license}))
+ {
+ $files->{$file}->{license_override}=$override->{license};
+ }
+ if(length($override->{license_text}))
+ {
+ $files->{$file}->{license_text_override}=$override->{license_text};
+ }
+ }
}
}
unless(keys(%$new))
{
warn("$me: no new/changed files found\n");
- return;
}
unless(open(NEW,">$NEWFILES"))
{
print NEW "File: $file\n";
print NEW "Hash: ", $new->{$file}->{hash}, "\n";
print NEW "Copyright: ", $new->{$file}->{copyright}, "\n";
- print NEW "License: ", $new->{$file}->{license}, "\n";
- print NEW "License_Text: \n";
- if($new->{$file}->{license_old})
+ if($new->{$file}->{copyright_guess})
{
- print NEW "#License_old: ", $new->{$file}->{license_old}, "\n";
+ print NEW "#Copyright_guess: ", $new->{$file}->{copyright_guess}, "\n";
}
- if($new->{$file}->{copyright_old})
+ print NEW "License: ", $new->{$file}->{license}, "\n";
+ if($new->{$file}->{license_guess})
{
- print NEW "#Copyright_old: ", $new->{$file}->{copyright_old}, "\n";
+ print NEW "#License_guess: ", $new->{$file}->{license_guess}, "\n";
}
- if($new->{$file}->{licence_text_old})
+ if($new->{$file}->{license_text})
{
- print NEW "#License_text_old: ", $new->{$file}->{licence_text_old}, "\n";
+ my @text=split(/\n/, $new->{$file}->{license_text});
+ print NEW "\t" . join("\n\t", @text), "\n";
}
print NEW "#Header: \n";
my @headerlines=split(/\n/, $new->{$file}->{header});
print NEW join("\n", @headerlines);
print NEW "\n\n";
}
+ if(@deleted_files)
+ {
+ print NEW map { "Deleted: $_\n"; } @deleted_files;
+ }
close NEW;
}
$in_license_text=1;
$license_text='';
}
+ elsif(/^Deleted:\s*(.*)/)
+ {
+ if(exists($files->{$1}))
+ {
+ delete($files->{$1});
+ }
+ }
else
{
warn("$me: $NEWFILES: line $line not recognized\n");
sub find_deleted
{
- my @deleted=();
my %newnames = map { $_ => 1 } @filenames;
for my $file (sort keys(%$files))
{
unless(exists($newnames{$file}))
{
- push(@deleted, $file);
+ push(@deleted_files, $file);
}
}
- if(@deleted)
+ if(@deleted_files)
{
print "Removed files:\n";
- print join("\n", @deleted),"\n";
+ print join("\n", @deleted_files),"\n";
}
}