1c50c785cSJohn Marino#! /usr/bin/env python 2c50c785cSJohn Marino 3*ef5ccd6cSJohn Marino# Copyright (C) 2011-2013 Free Software Foundation, Inc. 4*ef5ccd6cSJohn Marino# 5*ef5ccd6cSJohn Marino# This file is part of GDB. 6*ef5ccd6cSJohn Marino# 7*ef5ccd6cSJohn Marino# This program is free software; you can redistribute it and/or modify 8*ef5ccd6cSJohn Marino# it under the terms of the GNU General Public License as published by 9*ef5ccd6cSJohn Marino# the Free Software Foundation; either version 3 of the License, or 10*ef5ccd6cSJohn Marino# (at your option) any later version. 11*ef5ccd6cSJohn Marino# 12*ef5ccd6cSJohn Marino# This program is distributed in the hope that it will be useful, 13*ef5ccd6cSJohn Marino# but WITHOUT ANY WARRANTY; without even the implied warranty of 14*ef5ccd6cSJohn Marino# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*ef5ccd6cSJohn Marino# GNU General Public License for more details. 16*ef5ccd6cSJohn Marino# 17*ef5ccd6cSJohn Marino# You should have received a copy of the GNU General Public License 18*ef5ccd6cSJohn Marino# along with this program. If not, see <http://www.gnu.org/licenses/>. 19*ef5ccd6cSJohn Marino 20c50c785cSJohn Marino"""copyright.py 21c50c785cSJohn Marino 22*ef5ccd6cSJohn MarinoThis script updates the list of years in the copyright notices in 23*ef5ccd6cSJohn Marinomost files maintained by the GDB project. 24c50c785cSJohn Marino 25*ef5ccd6cSJohn MarinoUsage: cd src/gdb && python copyright.py 26*ef5ccd6cSJohn Marino 27*ef5ccd6cSJohn MarinoAlways review the output of this script before committing it! 28*ef5ccd6cSJohn MarinoA useful command to review the output is: 29*ef5ccd6cSJohn Marino % filterdiff -x \*.c -x \*.cc -x \*.h -x \*.exp updates.diff 30*ef5ccd6cSJohn MarinoThis removes the bulk of the changes which are most likely to be correct. 31c50c785cSJohn Marino""" 32c50c785cSJohn Marino 33c50c785cSJohn Marinoimport datetime 34c50c785cSJohn Marinoimport os 35c50c785cSJohn Marinoimport os.path 36*ef5ccd6cSJohn Marinoimport subprocess 37c50c785cSJohn Marino 38c50c785cSJohn Marino 39*ef5ccd6cSJohn Marinodef get_update_list(): 40*ef5ccd6cSJohn Marino """Return the list of files to update. 41*ef5ccd6cSJohn Marino 42*ef5ccd6cSJohn Marino Assumes that the current working directory when called is the root 43*ef5ccd6cSJohn Marino of the GDB source tree (NOT the gdb/ subdirectory!). The names of 44*ef5ccd6cSJohn Marino the files are relative to that root directory. 45c50c785cSJohn Marino """ 46*ef5ccd6cSJohn Marino result = [] 47*ef5ccd6cSJohn Marino for gdb_dir in ('gdb', 'sim', 'include/gdb'): 48*ef5ccd6cSJohn Marino for root, dirs, files in os.walk(gdb_dir, topdown=True): 49*ef5ccd6cSJohn Marino for dirname in dirs: 50*ef5ccd6cSJohn Marino reldirname = "%s/%s" % (root, dirname) 51*ef5ccd6cSJohn Marino if (dirname in EXCLUDE_ALL_LIST 52*ef5ccd6cSJohn Marino or reldirname in EXCLUDE_LIST 53*ef5ccd6cSJohn Marino or reldirname in NOT_FSF_LIST 54*ef5ccd6cSJohn Marino or reldirname in BY_HAND): 55*ef5ccd6cSJohn Marino # Prune this directory from our search list. 56*ef5ccd6cSJohn Marino dirs.remove(dirname) 57*ef5ccd6cSJohn Marino for filename in files: 58*ef5ccd6cSJohn Marino relpath = "%s/%s" % (root, filename) 59*ef5ccd6cSJohn Marino if (filename in EXCLUDE_ALL_LIST 60*ef5ccd6cSJohn Marino or relpath in EXCLUDE_LIST 61*ef5ccd6cSJohn Marino or relpath in NOT_FSF_LIST 62*ef5ccd6cSJohn Marino or relpath in BY_HAND): 63*ef5ccd6cSJohn Marino # Ignore this file. 64*ef5ccd6cSJohn Marino pass 65*ef5ccd6cSJohn Marino else: 66*ef5ccd6cSJohn Marino result.append(relpath) 67*ef5ccd6cSJohn Marino return result 68c50c785cSJohn Marino 69c50c785cSJohn Marino 70*ef5ccd6cSJohn Marinodef update_files(update_list): 71*ef5ccd6cSJohn Marino """Update the copyright header of the files in the given list. 72*ef5ccd6cSJohn Marino 73*ef5ccd6cSJohn Marino We use gnulib's update-copyright script for that. 74*ef5ccd6cSJohn Marino """ 75*ef5ccd6cSJohn Marino # We want to use year intervals in the copyright notices, and 76*ef5ccd6cSJohn Marino # all years should be collapsed to one single year interval, 77*ef5ccd6cSJohn Marino # even if there are "holes" in the list of years found in the 78*ef5ccd6cSJohn Marino # original copyright notice (OK'ed by the FSF, case [gnu.org #719834]). 79*ef5ccd6cSJohn Marino os.environ['UPDATE_COPYRIGHT_USE_INTERVALS'] = '2' 80*ef5ccd6cSJohn Marino 81*ef5ccd6cSJohn Marino # Perform the update, and save the output in a string. 82*ef5ccd6cSJohn Marino update_cmd = ['bash', 'gdb/gnulib/import/extra/update-copyright'] 83*ef5ccd6cSJohn Marino update_cmd += update_list 84*ef5ccd6cSJohn Marino 85*ef5ccd6cSJohn Marino p = subprocess.Popen(update_cmd, stdout=subprocess.PIPE, 86*ef5ccd6cSJohn Marino stderr=subprocess.STDOUT) 87*ef5ccd6cSJohn Marino update_out = p.communicate()[0] 88*ef5ccd6cSJohn Marino 89*ef5ccd6cSJohn Marino # Process the output. Typically, a lot of files do not have 90*ef5ccd6cSJohn Marino # a copyright notice :-(. The update-copyright script prints 91*ef5ccd6cSJohn Marino # a well defined warning when it did not find the copyright notice. 92*ef5ccd6cSJohn Marino # For each of those, do a sanity check and see if they may in fact 93*ef5ccd6cSJohn Marino # have one. For the files that are found not to have one, we filter 94*ef5ccd6cSJohn Marino # the line out from the output, since there is nothing more to do, 95*ef5ccd6cSJohn Marino # short of looking at each file and seeing which notice is appropriate. 96*ef5ccd6cSJohn Marino # Too much work! (~4,000 files listed as of 2012-01-03). 97*ef5ccd6cSJohn Marino update_out = update_out.splitlines() 98*ef5ccd6cSJohn Marino warning_string = ': warning: copyright statement not found' 99*ef5ccd6cSJohn Marino warning_len = len(warning_string) 100*ef5ccd6cSJohn Marino 101*ef5ccd6cSJohn Marino for line in update_out: 102*ef5ccd6cSJohn Marino if line.endswith('\n'): 103*ef5ccd6cSJohn Marino line = line[:-1] 104*ef5ccd6cSJohn Marino if line.endswith(warning_string): 105*ef5ccd6cSJohn Marino filename = line[:-warning_len] 106*ef5ccd6cSJohn Marino if may_have_copyright_notice(filename): 107*ef5ccd6cSJohn Marino print line 108*ef5ccd6cSJohn Marino else: 109*ef5ccd6cSJohn Marino # Unrecognized file format. !?! 110*ef5ccd6cSJohn Marino print "*** " + line 111*ef5ccd6cSJohn Marino 112*ef5ccd6cSJohn Marino 113*ef5ccd6cSJohn Marinodef may_have_copyright_notice(filename): 114*ef5ccd6cSJohn Marino """Check that the given file does not seem to have a copyright notice. 115*ef5ccd6cSJohn Marino 116*ef5ccd6cSJohn Marino The filename is relative to the root directory. 117*ef5ccd6cSJohn Marino This function assumes that the current working directory is that root 118*ef5ccd6cSJohn Marino directory. 119*ef5ccd6cSJohn Marino 120*ef5ccd6cSJohn Marino The algorigthm is fairly crude, meaning that it might return 121*ef5ccd6cSJohn Marino some false positives. I do not think it will return any false 122*ef5ccd6cSJohn Marino negatives... We might improve this function to handle more 123*ef5ccd6cSJohn Marino complex cases later... 124*ef5ccd6cSJohn Marino """ 125*ef5ccd6cSJohn Marino # For now, it may have a copyright notice if we find the word 126*ef5ccd6cSJohn Marino # "Copyright" at the (reasonable) start of the given file, say 127*ef5ccd6cSJohn Marino # 50 lines... 128*ef5ccd6cSJohn Marino MAX_LINES = 50 129*ef5ccd6cSJohn Marino 130*ef5ccd6cSJohn Marino fd = open(filename) 131*ef5ccd6cSJohn Marino 132*ef5ccd6cSJohn Marino lineno = 1 133*ef5ccd6cSJohn Marino for line in fd: 134*ef5ccd6cSJohn Marino if 'Copyright' in line: 135*ef5ccd6cSJohn Marino return True 136*ef5ccd6cSJohn Marino lineno += 1 137*ef5ccd6cSJohn Marino if lineno > 50: 138*ef5ccd6cSJohn Marino return False 139*ef5ccd6cSJohn Marino return False 140*ef5ccd6cSJohn Marino 141*ef5ccd6cSJohn Marino 142*ef5ccd6cSJohn Marinodef main (): 143*ef5ccd6cSJohn Marino """The main subprogram.""" 144*ef5ccd6cSJohn Marino if not os.path.isfile("gnulib/import/extra/update-copyright"): 145*ef5ccd6cSJohn Marino print "Error: This script must be called from the gdb directory." 146*ef5ccd6cSJohn Marino root_dir = os.path.dirname(os.getcwd()) 147*ef5ccd6cSJohn Marino os.chdir(root_dir) 148*ef5ccd6cSJohn Marino 149*ef5ccd6cSJohn Marino update_list = get_update_list() 150*ef5ccd6cSJohn Marino update_files (update_list) 151*ef5ccd6cSJohn Marino 152*ef5ccd6cSJohn Marino # Remind the user that some files need to be updated by HAND... 153*ef5ccd6cSJohn Marino if BY_HAND: 154*ef5ccd6cSJohn Marino print 155*ef5ccd6cSJohn Marino print "\033[31mREMINDER: The following files must be updated by hand." \ 156*ef5ccd6cSJohn Marino "\033[0m" 157*ef5ccd6cSJohn Marino for filename in BY_HAND + MULTIPLE_COPYRIGHT_HEADERS: 158*ef5ccd6cSJohn Marino print " ", filename 159*ef5ccd6cSJohn Marino 160*ef5ccd6cSJohn Marino############################################################################ 161*ef5ccd6cSJohn Marino# 162*ef5ccd6cSJohn Marino# Some constants, placed at the end because they take up a lot of room. 163*ef5ccd6cSJohn Marino# The actual value of these constants is not significant to the understanding 164*ef5ccd6cSJohn Marino# of the script. 165*ef5ccd6cSJohn Marino# 166*ef5ccd6cSJohn Marino############################################################################ 167c50c785cSJohn Marino 168c50c785cSJohn Marino# Files which should not be modified, either because they are 169c50c785cSJohn Marino# generated, non-FSF, or otherwise special (e.g. license text, 170c50c785cSJohn Marino# or test cases which must be sensitive to line numbering). 171*ef5ccd6cSJohn Marino# 172*ef5ccd6cSJohn Marino# Filenames are relative to the root directory. 173*ef5ccd6cSJohn MarinoEXCLUDE_LIST = ( 174*ef5ccd6cSJohn Marino 'gdb/CONTRIBUTE', 175*ef5ccd6cSJohn Marino 'gdb/gnulib' 176c50c785cSJohn Marino) 177c50c785cSJohn Marino 178*ef5ccd6cSJohn Marino# Files which should not be modified, either because they are 179*ef5ccd6cSJohn Marino# generated, non-FSF, or otherwise special (e.g. license text, 180*ef5ccd6cSJohn Marino# or test cases which must be sensitive to line numbering). 181*ef5ccd6cSJohn Marino# 182*ef5ccd6cSJohn Marino# Matches any file or directory name anywhere. Use with caution. 183*ef5ccd6cSJohn Marino# This is mostly for files that can be found in multiple directories. 184*ef5ccd6cSJohn Marino# Eg: We want all files named COPYING to be left untouched. 185c50c785cSJohn Marino 186*ef5ccd6cSJohn MarinoEXCLUDE_ALL_LIST = ( 187*ef5ccd6cSJohn Marino "COPYING", "COPYING.LIB", "CVS", "configure", "copying.c", 188*ef5ccd6cSJohn Marino "fdl.texi", "gpl.texi", "aclocal.m4", 189c50c785cSJohn Marino) 190c50c785cSJohn Marino 191*ef5ccd6cSJohn Marino# The list of files to update by hand. 192*ef5ccd6cSJohn MarinoBY_HAND = ( 193*ef5ccd6cSJohn Marino # These files are sensitive to line numbering. 194*ef5ccd6cSJohn Marino "gdb/testsuite/gdb.base/step-line.inp", 195*ef5ccd6cSJohn Marino "gdb/testsuite/gdb.base/step-line.c", 196*ef5ccd6cSJohn Marino) 197c50c785cSJohn Marino 198*ef5ccd6cSJohn Marino# Files containing multiple copyright headers. This script is only 199*ef5ccd6cSJohn Marino# fixing the first one it finds, so we need to finish the update 200*ef5ccd6cSJohn Marino# by hand. 201*ef5ccd6cSJohn MarinoMULTIPLE_COPYRIGHT_HEADERS = ( 202*ef5ccd6cSJohn Marino "gdb/doc/gdb.texinfo", 203*ef5ccd6cSJohn Marino "gdb/doc/refcard.tex", 204*ef5ccd6cSJohn Marino "gdb/gdbarch.sh", 205*ef5ccd6cSJohn Marino) 206c50c785cSJohn Marino 207*ef5ccd6cSJohn Marino# The list of file which have a copyright, but not head by the FSF. 208*ef5ccd6cSJohn Marino# Filenames are relative to the root directory. 209*ef5ccd6cSJohn MarinoNOT_FSF_LIST = ( 210*ef5ccd6cSJohn Marino "gdb/exc_request.defs", 211*ef5ccd6cSJohn Marino "gdb/gdbtk", 212*ef5ccd6cSJohn Marino "gdb/testsuite/gdb.gdbtk/", 213*ef5ccd6cSJohn Marino "sim/arm/armemu.h", "sim/arm/armos.c", "sim/arm/gdbhost.c", 214*ef5ccd6cSJohn Marino "sim/arm/dbg_hif.h", "sim/arm/dbg_conf.h", "sim/arm/communicate.h", 215*ef5ccd6cSJohn Marino "sim/arm/armos.h", "sim/arm/armcopro.c", "sim/arm/armemu.c", 216*ef5ccd6cSJohn Marino "sim/arm/kid.c", "sim/arm/thumbemu.c", "sim/arm/armdefs.h", 217*ef5ccd6cSJohn Marino "sim/arm/armopts.h", "sim/arm/dbg_cp.h", "sim/arm/dbg_rdi.h", 218*ef5ccd6cSJohn Marino "sim/arm/parent.c", "sim/arm/armsupp.c", "sim/arm/armrdi.c", 219*ef5ccd6cSJohn Marino "sim/arm/bag.c", "sim/arm/armvirt.c", "sim/arm/main.c", "sim/arm/bag.h", 220*ef5ccd6cSJohn Marino "sim/arm/communicate.c", "sim/arm/gdbhost.h", "sim/arm/armfpe.h", 221*ef5ccd6cSJohn Marino "sim/arm/arminit.c", 222*ef5ccd6cSJohn Marino "sim/common/cgen-fpu.c", "sim/common/cgen-fpu.h", 223*ef5ccd6cSJohn Marino "sim/common/cgen-accfp.c", 224*ef5ccd6cSJohn Marino "sim/erc32/sis.h", "sim/erc32/erc32.c", "sim/erc32/func.c", 225*ef5ccd6cSJohn Marino "sim/erc32/float.c", "sim/erc32/interf.c", "sim/erc32/sis.c", 226*ef5ccd6cSJohn Marino "sim/erc32/exec.c", 227*ef5ccd6cSJohn Marino "sim/mips/m16run.c", "sim/mips/sim-main.c", 228*ef5ccd6cSJohn Marino "sim/moxie/moxie-gdb.dts", 229*ef5ccd6cSJohn Marino # Not a single file in sim/ppc/ appears to be copyright FSF :-(. 230*ef5ccd6cSJohn Marino "sim/ppc/filter.h", "sim/ppc/gen-support.h", "sim/ppc/ld-insn.h", 231*ef5ccd6cSJohn Marino "sim/ppc/hw_sem.c", "sim/ppc/hw_disk.c", "sim/ppc/idecode_branch.h", 232*ef5ccd6cSJohn Marino "sim/ppc/sim-endian.h", "sim/ppc/table.c", "sim/ppc/hw_core.c", 233*ef5ccd6cSJohn Marino "sim/ppc/gen-support.c", "sim/ppc/gen-semantics.h", "sim/ppc/cpu.h", 234*ef5ccd6cSJohn Marino "sim/ppc/sim_callbacks.h", "sim/ppc/RUN", "sim/ppc/Makefile.in", 235*ef5ccd6cSJohn Marino "sim/ppc/emul_chirp.c", "sim/ppc/hw_nvram.c", "sim/ppc/dc-test.01", 236*ef5ccd6cSJohn Marino "sim/ppc/hw_phb.c", "sim/ppc/hw_eeprom.c", "sim/ppc/bits.h", 237*ef5ccd6cSJohn Marino "sim/ppc/hw_vm.c", "sim/ppc/cap.h", "sim/ppc/os_emul.h", 238*ef5ccd6cSJohn Marino "sim/ppc/options.h", "sim/ppc/gen-idecode.c", "sim/ppc/filter.c", 239*ef5ccd6cSJohn Marino "sim/ppc/corefile-n.h", "sim/ppc/std-config.h", "sim/ppc/ld-decode.h", 240*ef5ccd6cSJohn Marino "sim/ppc/filter_filename.h", "sim/ppc/hw_shm.c", 241*ef5ccd6cSJohn Marino "sim/ppc/pk_disklabel.c", "sim/ppc/dc-simple", "sim/ppc/misc.h", 242*ef5ccd6cSJohn Marino "sim/ppc/device_table.h", "sim/ppc/ld-insn.c", "sim/ppc/inline.c", 243*ef5ccd6cSJohn Marino "sim/ppc/emul_bugapi.h", "sim/ppc/hw_cpu.h", "sim/ppc/debug.h", 244*ef5ccd6cSJohn Marino "sim/ppc/hw_ide.c", "sim/ppc/debug.c", "sim/ppc/gen-itable.h", 245*ef5ccd6cSJohn Marino "sim/ppc/interrupts.c", "sim/ppc/hw_glue.c", "sim/ppc/emul_unix.c", 246*ef5ccd6cSJohn Marino "sim/ppc/sim_calls.c", "sim/ppc/dc-complex", "sim/ppc/ld-cache.c", 247*ef5ccd6cSJohn Marino "sim/ppc/registers.h", "sim/ppc/dc-test.02", "sim/ppc/options.c", 248*ef5ccd6cSJohn Marino "sim/ppc/igen.h", "sim/ppc/registers.c", "sim/ppc/device.h", 249*ef5ccd6cSJohn Marino "sim/ppc/emul_chirp.h", "sim/ppc/hw_register.c", "sim/ppc/hw_init.c", 250*ef5ccd6cSJohn Marino "sim/ppc/sim-endian-n.h", "sim/ppc/filter_filename.c", 251*ef5ccd6cSJohn Marino "sim/ppc/bits.c", "sim/ppc/idecode_fields.h", "sim/ppc/hw_memory.c", 252*ef5ccd6cSJohn Marino "sim/ppc/misc.c", "sim/ppc/double.c", "sim/ppc/psim.h", 253*ef5ccd6cSJohn Marino "sim/ppc/hw_trace.c", "sim/ppc/emul_netbsd.h", "sim/ppc/psim.c", 254*ef5ccd6cSJohn Marino "sim/ppc/ppc-instructions", "sim/ppc/tree.h", "sim/ppc/README", 255*ef5ccd6cSJohn Marino "sim/ppc/gen-icache.h", "sim/ppc/gen-model.h", "sim/ppc/ld-cache.h", 256*ef5ccd6cSJohn Marino "sim/ppc/mon.c", "sim/ppc/corefile.h", "sim/ppc/vm.c", 257*ef5ccd6cSJohn Marino "sim/ppc/INSTALL", "sim/ppc/gen-model.c", "sim/ppc/hw_cpu.c", 258*ef5ccd6cSJohn Marino "sim/ppc/corefile.c", "sim/ppc/hw_opic.c", "sim/ppc/gen-icache.c", 259*ef5ccd6cSJohn Marino "sim/ppc/events.h", "sim/ppc/os_emul.c", "sim/ppc/emul_generic.c", 260*ef5ccd6cSJohn Marino "sim/ppc/main.c", "sim/ppc/hw_com.c", "sim/ppc/gen-semantics.c", 261*ef5ccd6cSJohn Marino "sim/ppc/emul_bugapi.c", "sim/ppc/device.c", "sim/ppc/emul_generic.h", 262*ef5ccd6cSJohn Marino "sim/ppc/tree.c", "sim/ppc/mon.h", "sim/ppc/interrupts.h", 263*ef5ccd6cSJohn Marino "sim/ppc/cap.c", "sim/ppc/cpu.c", "sim/ppc/hw_phb.h", 264*ef5ccd6cSJohn Marino "sim/ppc/device_table.c", "sim/ppc/lf.c", "sim/ppc/lf.c", 265*ef5ccd6cSJohn Marino "sim/ppc/dc-stupid", "sim/ppc/hw_pal.c", "sim/ppc/ppc-spr-table", 266*ef5ccd6cSJohn Marino "sim/ppc/emul_unix.h", "sim/ppc/words.h", "sim/ppc/basics.h", 267*ef5ccd6cSJohn Marino "sim/ppc/hw_htab.c", "sim/ppc/lf.h", "sim/ppc/ld-decode.c", 268*ef5ccd6cSJohn Marino "sim/ppc/sim-endian.c", "sim/ppc/gen-itable.c", 269*ef5ccd6cSJohn Marino "sim/ppc/idecode_expression.h", "sim/ppc/table.h", "sim/ppc/dgen.c", 270*ef5ccd6cSJohn Marino "sim/ppc/events.c", "sim/ppc/gen-idecode.h", "sim/ppc/emul_netbsd.c", 271*ef5ccd6cSJohn Marino "sim/ppc/igen.c", "sim/ppc/vm_n.h", "sim/ppc/vm.h", 272*ef5ccd6cSJohn Marino "sim/ppc/hw_iobus.c", "sim/ppc/inline.h", 273*ef5ccd6cSJohn Marino "sim/testsuite/sim/bfin/s21.s", "sim/testsuite/sim/mips/mips32-dsp2.s", 274*ef5ccd6cSJohn Marino) 275c50c785cSJohn Marino 276c50c785cSJohn Marinoif __name__ == "__main__": 277*ef5ccd6cSJohn Marino main() 278c50c785cSJohn Marino 279