1#!/usr/bin/perl -w 2# This script was originally based on the script of the same name from 3# the KDE SDK (by dfaure@kde.org) 4# 5# This version is 6# Copyright (C) 2007, 2008 Adam D. Barratt 7# Copyright (C) 2012 Francesco Poli 8# 9# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 2 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License along 20# with this program. If not, see <http://www.gnu.org/licenses/>. 21 22=head1 NAME 23 24licensecheck - simple license checker for source files 25 26=head1 SYNOPSIS 27 28B<licensecheck> B<--help>|B<--version> 29 30B<licensecheck> [B<--no-conf>] [B<--verbose>] [B<--copyright>] 31[B<-l>|B<--lines=>I<N>] [B<-i>|B<--ignore=>I<regex>] [B<-c>|B<--check=>I<regex>] 32[B<-m>|B<--machine>] [B<-r>|B<--recursive>] 33I<list of files and directories to check> 34 35=head1 DESCRIPTION 36 37B<licensecheck> attempts to determine the license that applies to each file 38passed to it, by searching the start of the file for text belonging to 39various licenses. 40 41If any of the arguments passed are directories, B<licensecheck> will add 42the files contained within to the list of files to process. 43 44=head1 OPTIONS 45 46=over 4 47 48=item B<--verbose>, B<--no-verbose> 49 50Specify whether to output the text being processed from each file before 51the corresponding license information. 52 53Default is to be quiet. 54 55=item B<-l=>I<N>, B<--lines=>I<N> 56 57Specify the number of lines of each file's header which should be parsed 58for license information. (Default is 60). 59 60=item B<-i=>I<regex>, B<--ignore=>I<regex> 61 62When processing the list of files and directories, the regular 63expression specified by this option will be used to indicate those which 64should not be considered (e.g. backup files, VCS metadata). 65 66=item B<-r>, B<--recursive> 67 68Specify that the contents of directories should be added 69recursively. 70 71=item B<-c=>I<regex>, B<--check=>I<regex> 72 73Specify a pattern against which filenames will be matched in order to 74decide which files to check the license of. 75 76The default includes common source files. 77 78=item B<--copyright> 79 80Also display copyright text found within the file 81 82=item B<-m>, B<--machine> 83 84Display the information in a machine readable way, i.e. in the form 85<file><tab><license>[<tab><copyright>] so that it can be easily sorted 86and/or filtered, e.g. with the B<awk> and B<sort> commands. 87Note that using the B<--verbose> option will kill the readability. 88 89=item B<--no-conf>, B<--noconf> 90 91Do not read any configuration files. This can only be used as the first 92option given on the command-line. 93 94=back 95 96=head1 CONFIGURATION VARIABLES 97 98The two configuration files F</etc/devscripts.conf> and 99F<~/.devscripts> are sourced by a shell in that order to set 100configuration variables. Command line options can be used to override 101configuration file settings. Environment variable settings are 102ignored for this purpose. The currently recognised variables are: 103 104=over 4 105 106=item B<LICENSECHECK_VERBOSE> 107 108If this is set to I<yes>, then it is the same as the B<--verbose> command 109line parameter being used. The default is I<no>. 110 111=item B<LICENSECHECK_PARSELINES> 112 113If this is set to a positive number then the specified number of lines 114at the start of each file will be read whilst attempting to determine 115the license(s) in use. This is equivalent to the B<--lines> command line 116option. 117 118=back 119 120=head1 LICENSE 121 122This code is copyright by Adam D. Barratt <I<adam@adam-barratt.org.uk>>, 123all rights reserved; based on a script of the same name from the KDE 124SDK, which is copyright by <I<dfaure@kde.org>>. 125This program comes with ABSOLUTELY NO WARRANTY. 126You are free to redistribute this code under the terms of the GNU 127General Public License, version 2 or later. 128 129=head1 AUTHOR 130 131Adam D. Barratt <adam@adam-barratt.org.uk> 132 133=cut 134 135use strict; 136use warnings; 137use Getopt::Long qw(:config gnu_getopt); 138use File::Basename; 139use Tie::File; 140use Fcntl 'O_RDONLY'; 141 142sub fatal($); 143sub parse_copyright($); 144sub parselicense($); 145sub remove_comments($); 146 147my $progname = basename($0); 148 149# From dpkg-source 150my $default_ignore_regex = ' 151# Ignore general backup files 152(?:^|/).*~$| 153# Ignore emacs recovery files 154(?:^|/)\.#.*$| 155# Ignore vi swap files 156(?:^|/)\..*\.swp$| 157# Ignore baz-style junk files or directories 158(?:^|/),,.*(?:$|/.*$)| 159# File-names that should be ignored (never directories) 160(?:^|/)(?:DEADJOE|\.cvsignore|\.arch-inventory|\.bzrignore|\.gitignore)$| 161# File or directory names that should be ignored 162(?:^|/)(?:CVS|RCS|\.deps|\{arch\}|\.arch-ids|\.svn|\.hg|_darcs|\.git| 163\.shelf|_MTN|\.bzr(?:\.backup|tags)?)(?:$|/.*$) 164'; 165 166# Take out comments and newlines 167$default_ignore_regex =~ s/^#.*$//mg; 168$default_ignore_regex =~ s/\n//sg; 169 170my $default_check_regex = '\.(c(c|pp|xx)?|h(h|pp|xx)?|f(77|90)?|p(l|m)|xs|sh|php|py(|x)|rb|java|vala|el|sc(i|e)|cs|pas|inc|dtd|xsl|mod|m|tex|mli?)$'; 171 172my $modified_conf_msg; 173 174my ($opt_verbose, $opt_lines, $opt_noconf) = ('', '', ''); 175my $opt_ignore_regex = $default_ignore_regex; 176my $opt_check_regex = $default_check_regex; 177my $opt_recursive = 0; 178my $opt_copyright = 0; 179my $opt_machine = 0; 180my ($opt_help, $opt_version); 181my $def_lines = 60; 182 183# Read configuration files and then command line 184# This is boilerplate 185 186if (@ARGV and $ARGV[0] =~ /^--no-?conf$/) { 187 $modified_conf_msg = " (no configuration files read)"; 188 shift; 189} else { 190 my @config_files = ('/etc/devscripts.conf', '~/.devscripts'); 191 my %config_vars = ( 192 'LICENSECHECK_VERBOSE' => 'no', 193 'LICENSECHECK_PARSELINES' => $def_lines, 194 ); 195 my %config_default = %config_vars; 196 197 my $shell_cmd; 198 # Set defaults 199 foreach my $var (keys %config_vars) { 200 $shell_cmd .= qq[$var="$config_vars{$var}";\n]; 201 } 202 $shell_cmd .= 'for file in ' . join(" ", @config_files) . "; do\n"; 203 $shell_cmd .= '[ -f $file ] && . $file; done;' . "\n"; 204 # Read back values 205 foreach my $var (keys %config_vars) { $shell_cmd .= "echo \$$var;\n" } 206 my $shell_out = `/bin/bash -c '$shell_cmd'`; 207 @config_vars{keys %config_vars} = split /\n/, $shell_out, -1; 208 209 # Check validity 210 $config_vars{'LICENSECHECK_VERBOSE'} =~ /^(yes|no)$/ 211 or $config_vars{'LICENSECHECK_VERBOSE'} = 'no'; 212 $config_vars{'LICENSECHECK_PARSELINES'} =~ /^[1-9][0-9]*$/ 213 or $config_vars{'LICENSECHECK_PARSELINES'} = $def_lines; 214 215 foreach my $var (sort keys %config_vars) { 216 if ($config_vars{$var} ne $config_default{$var}) { 217 $modified_conf_msg .= " $var=$config_vars{$var}\n"; 218 } 219 } 220 $modified_conf_msg ||= " (none)\n"; 221 chomp $modified_conf_msg; 222 223 $opt_verbose = $config_vars{'LICENSECHECK_VERBOSE'} eq 'yes' ? 1 : 0; 224 $opt_lines = $config_vars{'LICENSECHECK_PARSELINES'}; 225} 226 227GetOptions("help|h" => \$opt_help, 228 "version|v" => \$opt_version, 229 "verbose!" => \$opt_verbose, 230 "lines|l=i" => \$opt_lines, 231 "ignore|i=s" => \$opt_ignore_regex, 232 "recursive|r" => \$opt_recursive, 233 "check|c=s" => \$opt_check_regex, 234 "copyright" => \$opt_copyright, 235 "machine|m" => \$opt_machine, 236 "noconf" => \$opt_noconf, 237 "no-conf" => \$opt_noconf, 238 ) 239 or die "Usage: $progname [options] filelist\nRun $progname --help for more details\n"; 240 241$opt_lines = $def_lines if $opt_lines !~ /^[1-9][0-9]*$/; 242 243if ($opt_noconf) { 244 fatal "--no-conf is only acceptable as the first command-line option!"; 245} 246if ($opt_help) { help(); exit 0; } 247if ($opt_version) { version(); exit 0; } 248 249die "Usage: $progname [options] filelist\nRun $progname --help for more details\n" unless @ARGV; 250 251$opt_lines = $def_lines if not defined $opt_lines; 252 253my @files = (); 254my @find_args = (); 255my $files_count = @ARGV; 256 257push @find_args, qw(-not ( -path */LayoutTests/* -prune ) ); 258push @find_args, qw(-not ( -path */out/Debug/* -prune ) ); 259push @find_args, qw(-not ( -path */out/Release/* -prune ) ); 260push @find_args, qw(-not ( -path *.git* -prune ) ); 261push @find_args, qw(-not ( -path *.svn* -prune ) ); 262 263push @find_args, qw(-maxdepth 1) unless $opt_recursive; 264push @find_args, qw(-follow -type f -print); 265 266while (@ARGV) { 267 my $file = shift @ARGV; 268 269 if (-d $file) { 270 open FIND, '-|', 'find', $file, @find_args 271 or die "$progname: couldn't exec find: $!\n"; 272 273 while (<FIND>) { 274 chomp; 275 next unless m%$opt_check_regex%; 276 # Skip empty files 277 next if (-z $_); 278 push @files, $_ unless m%$opt_ignore_regex%; 279 } 280 close FIND; 281 } else { 282 next unless ($files_count == 1) or $file =~ m%$opt_check_regex%; 283 push @files, $file unless $file =~ m%$opt_ignore_regex%; 284 } 285} 286 287while (@files) { 288 my $file = shift @files; 289 my $header = ''; 290 my $copyright_match; 291 my $copyright = ''; 292 my $license = ''; 293 my %copyrights; 294 295 open (F, "<$file") or die "Unable to access $file\n"; 296 while (<F>) { 297 last if ($. > $opt_lines); 298 $header .= $_; 299 } 300 close(F); 301 302 $copyright = join(" / ", values %copyrights); 303 304 print qq(----- $file header -----\n$header----- end header -----\n\n) 305 if $opt_verbose; 306 307 remove_comments($header); 308 $license = parselicense($header); 309 310 # If no license in header, check footer (slow, because read file backwards) 311 # Need for instance for Perl files, which often use the footer 312 if ($license eq "UNKNOWN") { 313 my $footer = ''; 314 tie(my @file_lines, "Tie::File", $file, autochomp => 0, mode => O_RDONLY) or die("Unable to access $file\n"); 315 # Avoid indexing error if header is entire file 316 if ($#file_lines >= $opt_lines) { 317 foreach (@file_lines[-$opt_lines .. -1]) { 318 $footer .= $_; 319 } 320 } 321 print qq(----- $file footer -----\n$header----- end footer -----\n\n) 322 if $opt_verbose; 323 remove_comments($footer); 324 $license = parselicense($footer); 325 } 326 327 if ($opt_machine) { 328 print "$file\t$license"; 329 print "\t" . ($copyright or "*No copyright*") if $opt_copyright; 330 print "\n"; 331 } else { 332 print "$file: "; 333 print "*No copyright* " unless $copyright; 334 print $license . "\n"; 335 print " [Copyright: " . $copyright . "]\n" 336 if $copyright and $opt_copyright; 337 print "\n" if $opt_copyright; 338 } 339} 340 341sub remove_comments($) { 342 $_ = $_[0]; 343 # Remove Fortran comments 344 s/^[cC] //gm; 345 tr/\t\r\n/ /; 346 # Remove C / C++ comments 347 s#(\*/|/[/*])##g; 348 tr% A-Za-z.,@;0-9\(\)/-%%cd; 349 tr/ //s; 350 $_[0] = $_; 351} 352 353sub parse_copyright($) { 354 my $copyright = ''; 355 my $match; 356 357 my $copyright_indicator_regex = ' 358 (?:copyright # The full word 359 |copr\. # Legally-valid abbreviation 360 |\x{00a9} # Unicode character COPYRIGHT SIGN 361 |\xc2\xa9 # Unicode copyright sign encoded in iso8859 362 |\(c\) # Legally-null representation of sign 363 )'; 364 my $copyright_disindicator_regex = ' 365 \b(?:info(?:rmation)? # Discussing copyright information 366 |notice # Discussing the notice 367 |and|or # Part of a sentence 368 )\b'; 369 370 if (m%$copyright_indicator_regex(?::\s*|\s+)(\S.*)$%ix) { 371 $match = $1; 372 373 # Ignore lines matching "see foo for copyright information" etc. 374 if ($match !~ m%^\s*$copyright_disindicator_regex%ix) { 375 # De-cruft 376 $match =~ s/([,.])?\s*$//; 377 $match =~ s/$copyright_indicator_regex//igx; 378 $match =~ s/^\s+//; 379 $match =~ s/\s{2,}/ /g; 380 $match =~ s/\\@/@/g; 381 $copyright = $match; 382 } 383 } 384 385 return $copyright; 386} 387 388sub help { 389 print <<"EOF"; 390Usage: $progname [options] filename [filename ...] 391Valid options are: 392 --help, -h Display this message 393 --version, -v Display version and copyright info 394 --no-conf, --noconf Don't read devscripts config files; must be 395 the first option given 396 --verbose Display the header of each file before its 397 license information 398 --lines, -l Specify how many lines of the file header 399 should be parsed for license information 400 (Default: $def_lines) 401 --check, -c Specify a pattern indicating which files should 402 be checked 403 (Default: '$default_check_regex') 404 --machine, -m Display in a machine readable way (good for awk) 405 --recursive, -r Add the contents of directories recursively 406 --copyright Also display the file's copyright 407 --ignore, -i Specify that files / directories matching the 408 regular expression should be ignored when 409 checking files 410 (Default: '$default_ignore_regex') 411 412Default settings modified by devscripts configuration files: 413$modified_conf_msg 414EOF 415} 416 417sub version { 418 print <<"EOF"; 419This is $progname, from the Debian devscripts package, version ###VERSION### 420Copyright (C) 2007, 2008 by Adam D. Barratt <adam\@adam-barratt.org.uk>; based 421on a script of the same name from the KDE SDK by <dfaure\@kde.org>. 422 423This program comes with ABSOLUTELY NO WARRANTY. 424You are free to redistribute this code under the terms of the 425GNU General Public License, version 2, or (at your option) any 426later version. 427EOF 428} 429 430sub parselicense($) { 431 my ($licensetext) = @_; 432 433 my $gplver = ""; 434 my $lgplver = ""; 435 my $extrainfo = ""; 436 my $license = ""; 437 438 if ($licensetext =~ /version ([^, ]+?)[.,]? (?:\(?only\)?.? )?(?:of the GNU (Affero )?General Public License )?(as )?published by the Free Software Foundation/i or 439 $licensetext =~ /GNU (?:Affero )?General Public License (?:as )?published by the Free Software Foundation; version ([^, ]+?)[.,]? /i or 440 $licensetext =~ /GNU (?:Affero )?General Public License,? [Vv]ersion (\d+(?:\.\d+)?)[ \.]/) { 441 $gplver = " (v$1)"; 442 } elsif ($licensetext =~ /either version ([^ ]+)(?: of the License)?, or \(at your option\) any later version/) { 443 $gplver = " (v$1 or later)"; 444 } 445 446 if ($licensetext =~ /version ([^, ]+?)[.,]? (?:or later|or any later version) (?:of the GNU (?:Lesser |Library )General Public License )(as )?published by the Free Software Foundation/i or 447 $licensetext =~ /(?:GNU (?:Lesser |Library )|(?:Lesser|Library) GNU )General Public License (?:(?:as )?published by the Free Software Foundation;)?,? (?:either )?[Vv]ersion ([^, ]+?)(?: of the license)?[.,]? (?:or later|or (?:\(at your option\) )?any later version)/i or 448 $licensetext =~ /GNU (?:Lesser |Library )General Public License(?: \(LGPL\))?,? [Vv]ersion (\d+(?:\.\d+)?)[ \.]/) { 449 $lgplver = " (v$1 or later)"; 450 } 451 452 if ($licensetext =~ /permission (?:is (also granted|given))? to link (the code of )?this program with (any edition of )?(Qt|the Qt library)/i) { 453 $extrainfo = " (with Qt exception)$extrainfo" 454 } 455 456 if ($licensetext =~ /(All changes made in this file will be lost|DO NOT (EDIT|delete this file)|Generated (automatically|by|from)|generated.*file)/i) { 457 $license = "GENERATED FILE"; 458 } 459 460 if ($licensetext =~ /is (free software.? you can redistribute it and\/or modify it|licensed) under the terms of (version [^ ]+ of )?the (GNU (Library |Lesser )General Public License|LGPL)/i or 461 $licensetext =~ /(is distributed|may be used|can redistribute).*terms.*(LGPL|(Lesser|Library) GNU General Public License)/) { 462 if ($lgplver) { 463 $license = "LGPL$lgplver$extrainfo $license"; 464 } else { 465 $license = "LGPL (unversioned/unknown version) $license"; 466 } 467 } 468 469 if ($licensetext =~ /is free software.? you (can|may) redistribute it and\/or modify it under the terms of (?:version [^ ]+ (?:\(?only\)? )?of )?the GNU General Public License/i) { 470 $license = "GPL$gplver$extrainfo $license"; 471 } elsif ($licensetext =~ /is distributed under the terms of the GNU General Public License,/ 472 and $gplver) { 473 $license = "GPL$gplver$extrainfo $license"; 474 } elsif ($licensetext =~ /is distributed.*terms.*[^L]GPL/) { 475 if ($gplver) { 476 $license = "GPL$gplver$extrainfo $license"; 477 } else { 478 $license = "GPL (unversioned/unknown version) $license"; 479 } 480 } 481 482 if ($licensetext =~ /This file is part of the .*Qt GUI Toolkit. This file may be distributed under the terms of the Q Public License as defined/) { 483 $license = "QPL (part of Qt) $license"; 484 } elsif ($licensetext =~ /may be distributed under the terms of the Q Public License as defined/) { 485 $license = "QPL $license"; 486 } 487 488 if ($licensetext =~ /opensource\.org\/licenses\/mit/) { 489 $license = "MIT/X11 (BSD like) $license"; 490 } elsif ($licensetext =~ /Permission is hereby granted, free of charge, to any person obtaining a copy of this software and(\/or)? associated documentation files \(the (Software|Materials)\), to deal in the (Software|Materials)/) { 491 $license = "MIT/X11 (BSD like) $license"; 492 } elsif ($licensetext =~ /Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose/) { 493 $license = "MIT/X11 (BSD like) $license"; 494 } 495 496 if ($licensetext =~ /This file is distributed under the University of Illinois Open Source License/){ 497 $license = "University of Illinois/NCSA Open Source License (BSD like) $license"; 498 } 499 500 if ($licensetext =~ /Permission to use, copy, modify, and(\/or)? distribute this software (and its documentation )?for any purpose (with or )?without fee is hereby granted, provided.*(copyright|entire) notice.*all copies/i) { 501 $license = "ISC $license"; 502 } 503 504 if ($licensetext =~ /THIS SOFTWARE IS PROVIDED .*AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY/ || 505 $licensetext =~ /THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- ITY/) { 506 if ($licensetext =~ /All advertising materials mentioning features or use of this software must display the following/) { 507 $license = "BSD (4 clause) $license"; 508 } elsif ($licensetext =~ /be used to endorse or promote products derived from this software/) { 509 $license = "BSD (3 clause) $license"; 510 } elsif ($licensetext =~ /Redistributions of source code must retain the above copyright notice/) { 511 $license = "BSD (2 clause) $license"; 512 } else { 513 $license = "BSD $license"; 514 } 515 } elsif ($licensetext =~ /Use of this source code is governed by a BSD-style license/) { 516 $license = "BSD-like $license"; 517 } elsif ($licensetext =~ /BSD terms apply/) { 518 $license = "BSD-like $license"; 519 } elsif ($licensetext =~ /subject to the BSD License/) { 520 # TODO(sbc): remove this case once we fix: http://crbug.com/177268 521 $license = "BSD-like $license"; 522 } elsif ($licensetext =~ /license BSD/) { 523 $license = "BSD-like $license"; 524 } elsif ($licensetext =~ /GOVERNED BY A BSD-STYLE SOURCE LICENSE/) { 525 $license = "BSD-like $license"; 526 } 527 528 if ($licensetext =~ /Mozilla Public License( Version|, v.) ([^ ]+[^., ]),?/) { 529 $license = "MPL (v$2) $license"; 530 } 531 532 if ($licensetext =~ /Released under the terms of the Artistic License ([^ ]+)/) { 533 $license = "Artistic (v$1) $license"; 534 } 535 536 if ($licensetext =~ /is free software under the Artistic [Ll]icense/) { 537 $license = "Artistic $license"; 538 } 539 540 if ($licensetext =~ /This (program|library) is free software; you can redistribute it and\/or modify it under the same terms as Perl itself/) { 541 $license = "Perl $license"; 542 } 543 544 if ($licensetext =~ /under the terms of the Apache ([^ ]+) License OR version 2 of the GNU/) { 545 $license = "Apache (v$1) GPL (v2) $license"; 546 } elsif ($licensetext =~ /under the Apache License, Version ([^ ]+)/) { 547 $license = "Apache (v$1) $license"; 548 } 549 550 if ($licensetext =~ /(THE BEER-WARE LICENSE)/i) { 551 $license = "Beerware $license"; 552 } 553 554 if ($licensetext =~ /This source file is subject to version ([^ ]+) of the PHP license/) { 555 $license = "PHP (v$1) $license"; 556 } 557 558 if ($licensetext =~ /under the terms of the CeCILL /) { 559 $license = "CeCILL $license"; 560 } 561 562 if ($licensetext =~ /under the terms of the CeCILL-([^ ]+) /) { 563 $license = "CeCILL-$1 $license"; 564 } 565 566 if ($licensetext =~ /under the SGI Free Software (B License|License B)/) { 567 $license = "SGI Free Software License B $license"; 568 } 569 570 if ($licensetext =~ /in the public domain/i) { 571 $license = "Public domain $license"; 572 } 573 574 if ($licensetext =~ /terms of the Common Development and Distribution License(, Version ([^(]+))? \(the License\)/) { 575 $license = "CDDL " . ($1 ? "(v$2) " : '') . $license; 576 } 577 578 if ($licensetext =~ /Microsoft Permissive License \(Ms-PL\)/) { 579 $license = "Ms-PL $license"; 580 } 581 582 if ($licensetext =~ /as defined in and that are subject to the Apple Public Source License([ ,-]+Version ([^ ]+)?(\.))/) { 583 $license = "APSL " . ($1 ? "(v$2) " : '') . $license; 584 } elsif ($licensetext =~ /provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software/) { 585 # https://fedoraproject.org/wiki/Licensing/Apple_MIT_License 586 $license = "Apple MIT $license"; 587 } 588 589 if ($licensetext =~ /Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license \(the \"Software\"\)/ or 590 $licensetext =~ /Boost Software License([ ,-]+Version ([^ ]+)?(\.))/i) { 591 $license = "BSL " . ($1 ? "(v$2) " : '') . $license; 592 } 593 594 if ($licensetext =~ /PYTHON SOFTWARE FOUNDATION LICENSE (VERSION ([^ ]+))/i) { 595 $license = "PSF " . ($1 ? "(v$2) " : '') . $license; 596 } 597 598 if ($licensetext =~ /The origin of this software must not be misrepresented.*Altered source versions must be plainly marked as such.*This notice may not be removed or altered from any source distribution/ or 599 $licensetext =~ /see copyright notice in zlib\.h/) { 600 $license = "zlib/libpng $license"; 601 } elsif ($licensetext =~ /This code is released under the libpng license/) { 602 $license = "libpng $license"; 603 } 604 605 if ($licensetext =~ /under MIT license/) { 606 $license = "MIT/X11 (BSD like) $license"; 607 } 608 609 if ($licensetext =~ /License MIT(-| )License/) { 610 $license = "MIT/X11 (BSD like) $license"; 611 } 612 613 if ($licensetext =~ /As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice/) { 614 $license = $license . "with Bison parser exception"; 615 } 616 617 if ($licensetext =~ /As a special exception to the GNU General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program/) { 618 $license = $license . "with libtool exception"; 619 } 620 621 if ($licensetext =~ /These materials are protected by copyright laws and contain material proprietary to the Khronos Group, Inc\. You may use these materials for implementing Khronos specifications, without altering or removing any trademark, copyright or other notice from the specification/) { 622 $license = $license . "Khronos Group"; 623 } 624 625 $license = "UNKNOWN" unless $license; 626 627 # Remove trailing spaces. 628 $license =~ s/\s+$//; 629 630 return $license; 631} 632 633sub fatal($) { 634 my ($pack,$file,$line); 635 ($pack,$file,$line) = caller(); 636 (my $msg = "$progname: fatal error at line $line:\n@_\n") =~ tr/\0//d; 637 $msg =~ s/\n\n$/\n/; 638 die $msg; 639} 640