OSDN Git Service

Merge branch 'binutils' into tmp
[pf3gnuchains/pf3gnuchains4x.git] / gdb / copyright.py
diff --git a/gdb/copyright.py b/gdb/copyright.py
new file mode 100644 (file)
index 0000000..d2df65e
--- /dev/null
@@ -0,0 +1,278 @@
+#! /usr/bin/env python
+
+# Copyright (C) 2011-2012 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 os
+import os.path
+import subprocess
+
+# A list of prefixes that start a multi-line comment.  These prefixes
+# should not be repeatead when wraping long lines.
+MULTILINE_COMMENT_PREFIXES = (
+    '/*',    # C/C++
+    '<!--',  # XML
+    '{',     # Pascal
+)
+
+
+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', '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.
+    """
+    # Tell the update-copyright script that we do not want it to
+    # repeat the prefixes in MULTILINE_COMMENT_PREFIXES.
+    os.environ['MULTILINE_COMMENT_PREFIXES'] = \
+        '\n'.join(MULTILINE_COMMENT_PREFIXES)
+    # We want to use year intervals in the copyright notices.
+    os.environ['UPDATE_COPYRIGHT_USE_INTERVALS'] = '1'
+
+    # Perform the update, and save the output in a string.
+    update_cmd = ['bash', 'gdb/gnulib/extra/update-copyright'] + update_list
+    p = subprocess.Popen(update_cmd, stdout=subprocess.PIPE,
+                         stderr=subprocess.STDOUT)
+    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()
+    warning_string = ': warning: copyright statement not found'
+    warning_len = len(warning_string)
+
+    for line in update_out:
+        if line.endswith('\n'):
+            line = line[:-1]
+        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 algorigthm 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
+
+    fd = open(filename)
+
+    lineno = 1
+    for line in fd:
+        if 'Copyright' in line:
+            return True
+        lineno += 1
+        if lineno > 50:
+            return False
+    return False
+
+
+def main ():
+    """The main subprogram."""
+    if not os.path.isfile("gnulib/extra/update-copyright"):
+        print "Error: This script must be called from the gdb directory."
+    root_dir = os.path.dirname(os.getcwd())
+    os.chdir(root_dir)
+
+    update_list = get_update_list()
+    update_files (update_list)
+
+    # Remind the user that some files need to be updated by HAND...
+    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/gdbarch.c', 'gdb/gdbarch.h',
+    'gdb/gnulib'
+)
+
+# 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 = (
+    # These files are sensitive to line numbering.
+    "gdb/testsuite/gdb.base/step-line.inp",
+    "gdb/testsuite/gdb.base/step-line.c",
+)
+
+# The list of file which have a copyright, but not head by the FSF.
+# Filenames are relative to the root directory.
+NOT_FSF_LIST = (
+    "gdb/exc_request.defs",
+    "gdb/osf-share",
+    "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-fpu.h",
+    "sim/common/cgen-accfp.c", "sim/common/sim-fpu.c",
+    "sim/erc32/sis.h", "sim/erc32/erc32.c", "sim/erc32/func.c",
+    "sim/erc32/float.c", "sim/erc32/interf.c", "sim/erc32/sis.c",
+    "sim/erc32/exec.c",
+    "sim/mips/m16run.c", "sim/mips/sim-main.c",
+    "sim/mn10300/sim-main.h",
+    "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/sim/bfin/s21.s", "sim/testsuite/sim/mips/mips32-dsp2.s",
+)
+
+if __name__ == "__main__":
+    main()
+