123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- #! /usr/bin/env python3
- # Copyright (C) 2011-2022 Free Software Foundation, Inc.
- #
- # This file is part of GDB.
- #
- # 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/>.
- """copyright.py
- This script updates the list of years in the copyright notices in
- most files maintained by the GDB project.
- Usage: cd src/gdb && python copyright.py
- Always review the output of this script before committing it!
- A useful command to review the output is:
- % filterdiff -x \*.c -x \*.cc -x \*.h -x \*.exp updates.diff
- This removes the bulk of the changes which are most likely to be correct.
- """
- import datetime
- import locale
- import os
- import os.path
- import subprocess
- import sys
- def get_update_list():
- """Return the list of files to update.
- Assumes that the current working directory when called is the root
- of the GDB source tree (NOT the gdb/ subdirectory!). The names of
- the files are relative to that root directory.
- """
- result = []
- for gdb_dir in (
- "gdb",
- "gdbserver",
- "gdbsupport",
- "gnulib",
- "sim",
- "include/gdb",
- ):
- for root, dirs, files in os.walk(gdb_dir, topdown=True):
- for dirname in dirs:
- reldirname = "%s/%s" % (root, dirname)
- if (
- dirname in EXCLUDE_ALL_LIST
- or reldirname in EXCLUDE_LIST
- or reldirname in NOT_FSF_LIST
- or reldirname in BY_HAND
- ):
- # Prune this directory from our search list.
- dirs.remove(dirname)
- for filename in files:
- relpath = "%s/%s" % (root, filename)
- if (
- filename in EXCLUDE_ALL_LIST
- or relpath in EXCLUDE_LIST
- or relpath in NOT_FSF_LIST
- or relpath in BY_HAND
- ):
- # Ignore this file.
- pass
- else:
- result.append(relpath)
- return result
- def update_files(update_list):
- """Update the copyright header of the files in the given list.
- We use gnulib's update-copyright script for that.
- """
- # We want to use year intervals in the copyright notices, and
- # all years should be collapsed to one single year interval,
- # even if there are "holes" in the list of years found in the
- # original copyright notice (OK'ed by the FSF, case [gnu.org #719834]).
- os.environ["UPDATE_COPYRIGHT_USE_INTERVALS"] = "2"
- # Perform the update, and save the output in a string.
- update_cmd = ["bash", "gnulib/import/extra/update-copyright"]
- update_cmd += update_list
- p = subprocess.Popen(
- update_cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- encoding=locale.getpreferredencoding(),
- )
- update_out = p.communicate()[0]
- # Process the output. Typically, a lot of files do not have
- # a copyright notice :-(. The update-copyright script prints
- # a well defined warning when it did not find the copyright notice.
- # For each of those, do a sanity check and see if they may in fact
- # have one. For the files that are found not to have one, we filter
- # the line out from the output, since there is nothing more to do,
- # short of looking at each file and seeing which notice is appropriate.
- # Too much work! (~4,000 files listed as of 2012-01-03).
- update_out = update_out.splitlines(keepends=False)
- warning_string = ": warning: copyright statement not found"
- warning_len = len(warning_string)
- for line in update_out:
- if line.endswith(warning_string):
- filename = line[:-warning_len]
- if may_have_copyright_notice(filename):
- print(line)
- else:
- # Unrecognized file format. !?!
- print("*** " + line)
- def may_have_copyright_notice(filename):
- """Check that the given file does not seem to have a copyright notice.
- The filename is relative to the root directory.
- This function assumes that the current working directory is that root
- directory.
- The algorithm is fairly crude, meaning that it might return
- some false positives. I do not think it will return any false
- negatives... We might improve this function to handle more
- complex cases later...
- """
- # For now, it may have a copyright notice if we find the word
- # "Copyright" at the (reasonable) start of the given file, say
- # 50 lines...
- MAX_LINES = 50
- # We don't really know what encoding each file might be following,
- # so just open the file as a byte stream. We only need to search
- # for a pattern that should be the same regardless of encoding,
- # so that should be good enough.
- fd = open(filename, "rb")
- lineno = 1
- for line in fd:
- if b"Copyright" in line:
- return True
- lineno += 1
- if lineno > 50:
- return False
- return False
- def main():
- """The main subprogram."""
- root_dir = os.path.dirname(os.getcwd())
- os.chdir(root_dir)
- if not (
- os.path.isdir("gdb") and os.path.isfile("gnulib/import/extra/update-copyright")
- ):
- print("Error: This script must be called from the gdb directory.")
- sys.exit(1)
- update_list = get_update_list()
- update_files(update_list)
- # Remind the user that some files need to be updated by HAND...
- if MULTIPLE_COPYRIGHT_HEADERS:
- print()
- print(
- "\033[31m"
- "REMINDER: Multiple copyright headers must be updated by hand:"
- "\033[0m"
- )
- for filename in MULTIPLE_COPYRIGHT_HEADERS:
- print(" ", filename)
- if BY_HAND:
- print()
- print(
- "\033[31mREMINDER: The following files must be updated by hand." "\033[0m"
- )
- for filename in BY_HAND:
- print(" ", filename)
- ############################################################################
- #
- # Some constants, placed at the end because they take up a lot of room.
- # The actual value of these constants is not significant to the understanding
- # of the script.
- #
- ############################################################################
- # Files which should not be modified, either because they are
- # generated, non-FSF, or otherwise special (e.g. license text,
- # or test cases which must be sensitive to line numbering).
- #
- # Filenames are relative to the root directory.
- EXCLUDE_LIST = (
- "gdb/nat/glibc_thread_db.h",
- "gdb/CONTRIBUTE",
- "gdbsupport/Makefile.in",
- "gnulib/import",
- "gnulib/config.in",
- "gnulib/Makefile.in",
- )
- # Files which should not be modified, either because they are
- # generated, non-FSF, or otherwise special (e.g. license text,
- # or test cases which must be sensitive to line numbering).
- #
- # Matches any file or directory name anywhere. Use with caution.
- # This is mostly for files that can be found in multiple directories.
- # Eg: We want all files named COPYING to be left untouched.
- EXCLUDE_ALL_LIST = (
- "COPYING",
- "COPYING.LIB",
- "CVS",
- "configure",
- "copying.c",
- "fdl.texi",
- "gpl.texi",
- "aclocal.m4",
- )
- # The list of files to update by hand.
- BY_HAND = (
- # Nothing at the moment :-).
- )
- # Files containing multiple copyright headers. This script is only
- # fixing the first one it finds, so we need to finish the update
- # by hand.
- MULTIPLE_COPYRIGHT_HEADERS = (
- "gdb/doc/gdb.texinfo",
- "gdb/doc/refcard.tex",
- "gdb/syscalls/update-netbsd.sh",
- )
- # The list of file which have a copyright, but not held by the FSF.
- # Filenames are relative to the root directory.
- NOT_FSF_LIST = (
- "gdb/exc_request.defs",
- "gdb/gdbtk",
- "gdb/testsuite/gdb.gdbtk/",
- "sim/arm/armemu.h",
- "sim/arm/armos.c",
- "sim/arm/gdbhost.c",
- "sim/arm/dbg_hif.h",
- "sim/arm/dbg_conf.h",
- "sim/arm/communicate.h",
- "sim/arm/armos.h",
- "sim/arm/armcopro.c",
- "sim/arm/armemu.c",
- "sim/arm/kid.c",
- "sim/arm/thumbemu.c",
- "sim/arm/armdefs.h",
- "sim/arm/armopts.h",
- "sim/arm/dbg_cp.h",
- "sim/arm/dbg_rdi.h",
- "sim/arm/parent.c",
- "sim/arm/armsupp.c",
- "sim/arm/armrdi.c",
- "sim/arm/bag.c",
- "sim/arm/armvirt.c",
- "sim/arm/main.c",
- "sim/arm/bag.h",
- "sim/arm/communicate.c",
- "sim/arm/gdbhost.h",
- "sim/arm/armfpe.h",
- "sim/arm/arminit.c",
- "sim/common/cgen-fpu.c",
- "sim/common/cgen-fpu.h",
- "sim/common/cgen-accfp.c",
- "sim/mips/m16run.c",
- "sim/mips/sim-main.c",
- "sim/moxie/moxie-gdb.dts",
- # Not a single file in sim/ppc/ appears to be copyright FSF :-(.
- "sim/ppc/filter.h",
- "sim/ppc/gen-support.h",
- "sim/ppc/ld-insn.h",
- "sim/ppc/hw_sem.c",
- "sim/ppc/hw_disk.c",
- "sim/ppc/idecode_branch.h",
- "sim/ppc/sim-endian.h",
- "sim/ppc/table.c",
- "sim/ppc/hw_core.c",
- "sim/ppc/gen-support.c",
- "sim/ppc/gen-semantics.h",
- "sim/ppc/cpu.h",
- "sim/ppc/sim_callbacks.h",
- "sim/ppc/RUN",
- "sim/ppc/Makefile.in",
- "sim/ppc/emul_chirp.c",
- "sim/ppc/hw_nvram.c",
- "sim/ppc/dc-test.01",
- "sim/ppc/hw_phb.c",
- "sim/ppc/hw_eeprom.c",
- "sim/ppc/bits.h",
- "sim/ppc/hw_vm.c",
- "sim/ppc/cap.h",
- "sim/ppc/os_emul.h",
- "sim/ppc/options.h",
- "sim/ppc/gen-idecode.c",
- "sim/ppc/filter.c",
- "sim/ppc/corefile-n.h",
- "sim/ppc/std-config.h",
- "sim/ppc/ld-decode.h",
- "sim/ppc/filter_filename.h",
- "sim/ppc/hw_shm.c",
- "sim/ppc/pk_disklabel.c",
- "sim/ppc/dc-simple",
- "sim/ppc/misc.h",
- "sim/ppc/device_table.h",
- "sim/ppc/ld-insn.c",
- "sim/ppc/inline.c",
- "sim/ppc/emul_bugapi.h",
- "sim/ppc/hw_cpu.h",
- "sim/ppc/debug.h",
- "sim/ppc/hw_ide.c",
- "sim/ppc/debug.c",
- "sim/ppc/gen-itable.h",
- "sim/ppc/interrupts.c",
- "sim/ppc/hw_glue.c",
- "sim/ppc/emul_unix.c",
- "sim/ppc/sim_calls.c",
- "sim/ppc/dc-complex",
- "sim/ppc/ld-cache.c",
- "sim/ppc/registers.h",
- "sim/ppc/dc-test.02",
- "sim/ppc/options.c",
- "sim/ppc/igen.h",
- "sim/ppc/registers.c",
- "sim/ppc/device.h",
- "sim/ppc/emul_chirp.h",
- "sim/ppc/hw_register.c",
- "sim/ppc/hw_init.c",
- "sim/ppc/sim-endian-n.h",
- "sim/ppc/filter_filename.c",
- "sim/ppc/bits.c",
- "sim/ppc/idecode_fields.h",
- "sim/ppc/hw_memory.c",
- "sim/ppc/misc.c",
- "sim/ppc/double.c",
- "sim/ppc/psim.h",
- "sim/ppc/hw_trace.c",
- "sim/ppc/emul_netbsd.h",
- "sim/ppc/psim.c",
- "sim/ppc/ppc-instructions",
- "sim/ppc/tree.h",
- "sim/ppc/README",
- "sim/ppc/gen-icache.h",
- "sim/ppc/gen-model.h",
- "sim/ppc/ld-cache.h",
- "sim/ppc/mon.c",
- "sim/ppc/corefile.h",
- "sim/ppc/vm.c",
- "sim/ppc/INSTALL",
- "sim/ppc/gen-model.c",
- "sim/ppc/hw_cpu.c",
- "sim/ppc/corefile.c",
- "sim/ppc/hw_opic.c",
- "sim/ppc/gen-icache.c",
- "sim/ppc/events.h",
- "sim/ppc/os_emul.c",
- "sim/ppc/emul_generic.c",
- "sim/ppc/main.c",
- "sim/ppc/hw_com.c",
- "sim/ppc/gen-semantics.c",
- "sim/ppc/emul_bugapi.c",
- "sim/ppc/device.c",
- "sim/ppc/emul_generic.h",
- "sim/ppc/tree.c",
- "sim/ppc/mon.h",
- "sim/ppc/interrupts.h",
- "sim/ppc/cap.c",
- "sim/ppc/cpu.c",
- "sim/ppc/hw_phb.h",
- "sim/ppc/device_table.c",
- "sim/ppc/lf.c",
- "sim/ppc/lf.c",
- "sim/ppc/dc-stupid",
- "sim/ppc/hw_pal.c",
- "sim/ppc/ppc-spr-table",
- "sim/ppc/emul_unix.h",
- "sim/ppc/words.h",
- "sim/ppc/basics.h",
- "sim/ppc/hw_htab.c",
- "sim/ppc/lf.h",
- "sim/ppc/ld-decode.c",
- "sim/ppc/sim-endian.c",
- "sim/ppc/gen-itable.c",
- "sim/ppc/idecode_expression.h",
- "sim/ppc/table.h",
- "sim/ppc/dgen.c",
- "sim/ppc/events.c",
- "sim/ppc/gen-idecode.h",
- "sim/ppc/emul_netbsd.c",
- "sim/ppc/igen.c",
- "sim/ppc/vm_n.h",
- "sim/ppc/vm.h",
- "sim/ppc/hw_iobus.c",
- "sim/ppc/inline.h",
- "sim/testsuite/mips/mips32-dsp2.s",
- )
- if __name__ == "__main__":
- main()
|