-#!/usr/bin/python
+#!/usr/bin/env python3
#
-# Copyright (C) 2013 Free Software Foundation, Inc.
+# Copyright (C) 2013-2024 Free Software Foundation, Inc.
#
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# output has been vetted. You can instead pass the names of individual
# directories, including those that haven't been approved. So:
#
-# update-copyright.pl --this-year
+# update-copyright.py --this-year
#
# is the command that would be used at the beginning of a year to update
# all copyright notices (and possibly at other times to check whether
# new files have been added with old years). On the other hand:
#
-# update-copyright.pl --this-year libjava
+# update-copyright.py --this-year libitm
#
-# would run the script on just libjava/.
+# would run the script on just libitm/.
#
# Note that things like --version output strings must be updated before
# this script is run. There's already a separate procedure for that.
def __init__ (self):
self.skip_files = set()
self.skip_dirs = set()
- self.skip_extensions = set()
+ self.skip_extensions = set([
+ '.png',
+ '.pyc',
+ ])
self.fossilised_files = set()
self.own_files = set()
'COPYING3',
'COPYING3.LIB',
'LICENSE',
+ 'LICENSE.txt',
'fdl.texi',
'gpl_v3.texi',
'fdl-1.3.xml',
'gpl-3.0.xml',
+ 'gpl_v3_without_node.texi',
# Skip auto- and libtool-related files
'aclocal.m4',
def add_external_author (self, holder):
self.holders[holder] = None
- class BadYear():
+ class BadYear (Exception):
def __init__ (self, year):
self.year = year
# If it looks like the copyright is incomplete, add the next line.
while not self.is_complete (match):
try:
- next_line = file.next()
+ next_line = file.readline()
except StopIteration:
break
return (line != orig_line, line, next_line)
+ def guess_encoding (self, pathname):
+ for encoding in ('utf8', 'iso8859'):
+ try:
+ open(pathname, 'r', encoding=encoding).read()
+ return encoding
+ except UnicodeDecodeError:
+ pass
+ return None
+
def process_file (self, dir, filename, filter):
pathname = os.path.join (dir, filename)
if filename.endswith ('.tmp'):
lines = []
changed = False
line_filter = filter.get_line_filter (dir, filename)
- with open (pathname, 'r') as file:
+ mode = None
+ encoding = self.guess_encoding(pathname)
+ with open (pathname, 'r', encoding=encoding) as file:
prev = None
+ mode = os.fstat (file.fileno()).st_mode
for line in file:
while line:
next_line = None
# If something changed, write the new file out.
if changed and self.errors.ok():
tmp_pathname = pathname + '.tmp'
- with open (tmp_pathname, 'w') as file:
+ with open (tmp_pathname, 'w', encoding=encoding) as file:
for line in lines:
file.write (line)
+ os.fchmod (file.fileno(), mode)
if self.use_quilt:
subprocess.call (['quilt', 'add', pathname])
os.rename (tmp_pathname, pathname)
def process_tree (self, tree, filter):
for (dir, subdirs, filenames) in os.walk (tree):
# Don't recurse through directories that should be skipped.
- for i in xrange (len (subdirs) - 1, -1, -1):
+ for i in range (len (subdirs) - 1, -1, -1):
if filter.skip_dir (dir, subdirs[i]):
del subdirs[i]
self.skip_files |= set ([
# Not part of GCC
'math-68881.h',
+
+ # Weird ways to compose copyright year
+ 'GmcOptions.cc',
])
self.skip_dirs |= set ([
'.c',
'.C',
'.cc',
+ '.d',
'.h',
'.hs',
'.f',
'.go',
'.inc',
'.java',
+ '.mod',
+ '.rs'
])
def skip_file (self, dir, filename):
# and isn't updated.
if filename == 'README' and os.path.basename (dir) == 'g++.niklas':
return True
+ # Similarly params/README.
+ if filename == 'README' and os.path.basename (dir) == 'params':
+ return True
+ if filename == 'pdt_5.f03' and os.path.basename (dir) == 'gfortran.dg':
+ return True
return GenericFilter.skip_file (self, dir, filename)
class LibCppFilter (GenericFilter):
'soft-fp',
])
-class LibJavaFilter (GenericFilter):
+class LibPhobosFilter (GenericFilter):
def __init__ (self):
GenericFilter.__init__ (self)
- self.skip_dirs |= set ([
- # Handled separately.
- 'testsuite',
-
- # Not really part of the library
- 'contrib',
-
- # Imported from upstream
- 'classpath',
- 'libltdl',
+ self.skip_files |= set ([
+ # Source modules imported from upstream.
+ 'object.d',
+ '__builtins.di'
])
- def get_line_filter (self, dir, filename):
- if filename == 'NameDecoder.h':
- return re.compile ('.*NAME_COPYRIGHT')
- if filename == 'ICC_Profile.h':
- return re.compile ('.*icSigCopyrightTag')
- return GenericFilter.get_line_filter (self, dir, filename)
-
-class LibMudflapFilter (GenericFilter):
- def __init__ (self):
- GenericFilter.__init__ (self)
-
self.skip_dirs |= set ([
- # Handled separately.
- 'testsuite',
+ # Contains sources imported from upstream.
+ 'core',
+ 'etc',
+ 'gc',
+ 'gcstub',
+ 'rt',
+ 'std',
])
class LibStdCxxFilter (GenericFilter):
return re.compile ('// \(C\) Copyright Jeremy Siek')
return GenericFilter.get_line_filter (self, dir, filename)
+class ContribFilter(GenericFilter):
+ def __init__ (self):
+ GenericFilter.__init__ (self)
+
+ self.skip_files |= set ([
+ # A different copyrights.
+ 'unicode-license.txt',
+ 'Info.plist',
+ # Contains CR (^M).
+ 'repro_fail',
+ 'test_patches.txt',
+ ])
+
class GCCCopyright (Copyright):
def __init__ (self, errors):
Copyright.__init__ (self, errors)
self.add_external_author ('ARM')
self.add_external_author ('AdaCore')
+ self.add_external_author ('Advanced Micro Devices Inc.')
self.add_external_author ('Ami Tavory and Vladimir Dreizin, IBM-HRL.')
self.add_external_author ('Cavium Networks.')
+ self.add_external_author ('David Malcolm')
self.add_external_author ('Faraday Technology Corp.')
self.add_external_author ('Florida State University')
+ self.add_external_author ('Gerard Jungman')
self.add_external_author ('Greg Colvin and Beman Dawes.')
self.add_external_author ('Hewlett-Packard Company')
+ self.add_external_author ('Intel Corporation')
self.add_external_author ('Information Technology Industry Council.')
self.add_external_author ('James Theiler, Brian Gough')
self.add_external_author ('Makoto Matsumoto and Takuji Nishimura,')
+ self.add_external_author ('Mentor Graphics Corporation')
self.add_external_author ('National Research Council of Canada.')
+ self.add_external_author ('NVIDIA Corporation')
self.add_external_author ('Peter Dimov and Multi Media Ltd.')
self.add_external_author ('Peter Dimov')
self.add_external_author ('Pipeline Associates, Inc.')
self.add_external_author ('Silicon Graphics')
self.add_external_author ('Stephen L. Moshier')
self.add_external_author ('Sun Microsystems, Inc. All rights reserved.')
+ self.add_external_author ('The D Language Foundation, All Rights Reserved')
+ self.add_external_author ('The fast_float authors')
self.add_external_author ('The Go Authors. All rights reserved.')
self.add_external_author ('The Go Authors. All rights reserved.')
self.add_external_author ('The Go Authors.')
self.add_external_author ('The Regents of the University of California.')
+ self.add_external_author ('Ulf Adams')
self.add_external_author ('Unicode, Inc.')
+ self.add_external_author ('University of Illinois at Urbana-Champaign.')
self.add_external_author ('University of Toronto.')
+ self.add_external_author ('Yoshinori Sato')
class GCCCmdLine (CmdLine):
def __init__ (self):
self.add_dir ('.', TopLevelFilter())
# boehm-gc is imported from upstream.
+ self.add_dir ('c++tools')
self.add_dir ('config', ConfigFilter())
- # contrib isn't really part of GCC.
+ self.add_dir ('contrib', ContribFilter())
self.add_dir ('fixincludes')
self.add_dir ('gcc', GCCFilter())
self.add_dir (os.path.join ('gcc', 'testsuite'), TestsuiteFilter())
self.add_dir ('gnattools')
+ self.add_dir ('gotools')
self.add_dir ('include')
+ # intl is imported from upstream.
self.add_dir ('libada')
self.add_dir ('libatomic')
self.add_dir ('libbacktrace')
+ self.add_dir ('libcc1')
self.add_dir ('libcpp', LibCppFilter())
self.add_dir ('libdecnumber')
# libffi is imported from upstream.
self.add_dir ('libgcc', LibGCCFilter())
self.add_dir ('libgfortran')
+ # libgo is imported from upstream.
self.add_dir ('libgomp')
self.add_dir ('libiberty')
self.add_dir ('libitm')
- self.add_dir ('libjava', LibJavaFilter())
- self.add_dir (os.path.join ('libjava', 'testsuite'), TestsuiteFilter())
- self.add_dir ('libmudflap', LibMudflapFilter())
- self.add_dir (os.path.join ('libmudflap', 'testsuite'),
- TestsuiteFilter())
self.add_dir ('libobjc')
+ self.add_dir ('libphobos', LibPhobosFilter())
self.add_dir ('libquadmath')
- # libsanitiser is imported from upstream.
+ # libsanitizer is imported from upstream.
self.add_dir ('libssp')
self.add_dir ('libstdc++-v3', LibStdCxxFilter())
self.add_dir ('libvtv')
self.add_dir ('lto-plugin')
+ # maintainer-scripts maintainer-scripts
# zlib is imported from upstream.
self.default_dirs = [
+ 'c++tools',
+ 'contrib',
'gcc',
+ 'include',
'libada',
'libatomic',
'libbacktrace',
+ 'libcc1',
'libcpp',
'libdecnumber',
'libgcc',
'libgfortran',
'libgomp',
+ 'libiberty',
'libitm',
- 'libmudflap',
'libobjc',
+ 'libphobos',
+ 'libssp',
'libstdc++-v3',
+ 'libvtv',
+ 'lto-plugin',
]
GCCCmdLine().main()