GDB (API)
|
00001 #! /usr/bin/env python 00002 00003 # Copyright (C) 2011-2013 Free Software Foundation, Inc. 00004 # 00005 # This file is part of GDB. 00006 # 00007 # This program is free software; you can redistribute it and/or modify 00008 # it under the terms of the GNU General Public License as published by 00009 # the Free Software Foundation; either version 3 of the License, or 00010 # (at your option) any later version. 00011 # 00012 # This program is distributed in the hope that it will be useful, 00013 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 # GNU General Public License for more details. 00016 # 00017 # You should have received a copy of the GNU General Public License 00018 # along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 00020 """copyright.py 00021 00022 This script updates the list of years in the copyright notices in 00023 most files maintained by the GDB project. 00024 00025 Usage: cd src/gdb && python copyright.py 00026 00027 Always review the output of this script before committing it! 00028 A useful command to review the output is: 00029 % filterdiff -x \*.c -x \*.cc -x \*.h -x \*.exp updates.diff 00030 This removes the bulk of the changes which are most likely to be correct. 00031 """ 00032 00033 import datetime 00034 import os 00035 import os.path 00036 import subprocess 00037 00038 00039 def get_update_list(): 00040 """Return the list of files to update. 00041 00042 Assumes that the current working directory when called is the root 00043 of the GDB source tree (NOT the gdb/ subdirectory!). The names of 00044 the files are relative to that root directory. 00045 """ 00046 result = [] 00047 for gdb_dir in ('gdb', 'sim', 'include/gdb'): 00048 for root, dirs, files in os.walk(gdb_dir, topdown=True): 00049 for dirname in dirs: 00050 reldirname = "%s/%s" % (root, dirname) 00051 if (dirname in EXCLUDE_ALL_LIST 00052 or reldirname in EXCLUDE_LIST 00053 or reldirname in NOT_FSF_LIST 00054 or reldirname in BY_HAND): 00055 # Prune this directory from our search list. 00056 dirs.remove(dirname) 00057 for filename in files: 00058 relpath = "%s/%s" % (root, filename) 00059 if (filename in EXCLUDE_ALL_LIST 00060 or relpath in EXCLUDE_LIST 00061 or relpath in NOT_FSF_LIST 00062 or relpath in BY_HAND): 00063 # Ignore this file. 00064 pass 00065 else: 00066 result.append(relpath) 00067 return result 00068 00069 00070 def update_files(update_list): 00071 """Update the copyright header of the files in the given list. 00072 00073 We use gnulib's update-copyright script for that. 00074 """ 00075 # We want to use year intervals in the copyright notices, and 00076 # all years should be collapsed to one single year interval, 00077 # even if there are "holes" in the list of years found in the 00078 # original copyright notice (OK'ed by the FSF, case [gnu.org #719834]). 00079 os.environ['UPDATE_COPYRIGHT_USE_INTERVALS'] = '2' 00080 00081 # Perform the update, and save the output in a string. 00082 update_cmd = ['bash', 'gdb/gnulib/import/extra/update-copyright'] 00083 update_cmd += update_list 00084 00085 p = subprocess.Popen(update_cmd, stdout=subprocess.PIPE, 00086 stderr=subprocess.STDOUT) 00087 update_out = p.communicate()[0] 00088 00089 # Process the output. Typically, a lot of files do not have 00090 # a copyright notice :-(. The update-copyright script prints 00091 # a well defined warning when it did not find the copyright notice. 00092 # For each of those, do a sanity check and see if they may in fact 00093 # have one. For the files that are found not to have one, we filter 00094 # the line out from the output, since there is nothing more to do, 00095 # short of looking at each file and seeing which notice is appropriate. 00096 # Too much work! (~4,000 files listed as of 2012-01-03). 00097 update_out = update_out.splitlines() 00098 warning_string = ': warning: copyright statement not found' 00099 warning_len = len(warning_string) 00100 00101 for line in update_out: 00102 if line.endswith('\n'): 00103 line = line[:-1] 00104 if line.endswith(warning_string): 00105 filename = line[:-warning_len] 00106 if may_have_copyright_notice(filename): 00107 print line 00108 else: 00109 # Unrecognized file format. !?! 00110 print "*** " + line 00111 00112 00113 def may_have_copyright_notice(filename): 00114 """Check that the given file does not seem to have a copyright notice. 00115 00116 The filename is relative to the root directory. 00117 This function assumes that the current working directory is that root 00118 directory. 00119 00120 The algorigthm is fairly crude, meaning that it might return 00121 some false positives. I do not think it will return any false 00122 negatives... We might improve this function to handle more 00123 complex cases later... 00124 """ 00125 # For now, it may have a copyright notice if we find the word 00126 # "Copyright" at the (reasonable) start of the given file, say 00127 # 50 lines... 00128 MAX_LINES = 50 00129 00130 fd = open(filename) 00131 00132 lineno = 1 00133 for line in fd: 00134 if 'Copyright' in line: 00135 return True 00136 lineno += 1 00137 if lineno > 50: 00138 return False 00139 return False 00140 00141 00142 def main (): 00143 """The main subprogram.""" 00144 if not os.path.isfile("gnulib/import/extra/update-copyright"): 00145 print "Error: This script must be called from the gdb directory." 00146 root_dir = os.path.dirname(os.getcwd()) 00147 os.chdir(root_dir) 00148 00149 update_list = get_update_list() 00150 update_files (update_list) 00151 00152 # Remind the user that some files need to be updated by HAND... 00153 if BY_HAND: 00154 print 00155 print "\033[31mREMINDER: The following files must be updated by hand." \ 00156 "\033[0m" 00157 for filename in BY_HAND + MULTIPLE_COPYRIGHT_HEADERS: 00158 print " ", filename 00159 00160 ############################################################################ 00161 # 00162 # Some constants, placed at the end because they take up a lot of room. 00163 # The actual value of these constants is not significant to the understanding 00164 # of the script. 00165 # 00166 ############################################################################ 00167 00168 # Files which should not be modified, either because they are 00169 # generated, non-FSF, or otherwise special (e.g. license text, 00170 # or test cases which must be sensitive to line numbering). 00171 # 00172 # Filenames are relative to the root directory. 00173 EXCLUDE_LIST = ( 00174 'gdb/common/glibc_thread_db.h', 00175 'gdb/CONTRIBUTE', 00176 'gdb/gnulib/import' 00177 ) 00178 00179 # Files which should not be modified, either because they are 00180 # generated, non-FSF, or otherwise special (e.g. license text, 00181 # or test cases which must be sensitive to line numbering). 00182 # 00183 # Matches any file or directory name anywhere. Use with caution. 00184 # This is mostly for files that can be found in multiple directories. 00185 # Eg: We want all files named COPYING to be left untouched. 00186 00187 EXCLUDE_ALL_LIST = ( 00188 "COPYING", "COPYING.LIB", "CVS", "configure", "copying.c", 00189 "fdl.texi", "gpl.texi", "aclocal.m4", 00190 ) 00191 00192 # The list of files to update by hand. 00193 BY_HAND = ( 00194 # These files are sensitive to line numbering. 00195 "gdb/testsuite/gdb.base/step-line.inp", 00196 "gdb/testsuite/gdb.base/step-line.c", 00197 ) 00198 00199 # Files containing multiple copyright headers. This script is only 00200 # fixing the first one it finds, so we need to finish the update 00201 # by hand. 00202 MULTIPLE_COPYRIGHT_HEADERS = ( 00203 "gdb/doc/gdb.texinfo", 00204 "gdb/doc/refcard.tex", 00205 "gdb/gdbarch.sh", 00206 ) 00207 00208 # The list of file which have a copyright, but not head by the FSF. 00209 # Filenames are relative to the root directory. 00210 NOT_FSF_LIST = ( 00211 "gdb/exc_request.defs", 00212 "gdb/gdbtk", 00213 "gdb/testsuite/gdb.gdbtk/", 00214 "sim/arm/armemu.h", "sim/arm/armos.c", "sim/arm/gdbhost.c", 00215 "sim/arm/dbg_hif.h", "sim/arm/dbg_conf.h", "sim/arm/communicate.h", 00216 "sim/arm/armos.h", "sim/arm/armcopro.c", "sim/arm/armemu.c", 00217 "sim/arm/kid.c", "sim/arm/thumbemu.c", "sim/arm/armdefs.h", 00218 "sim/arm/armopts.h", "sim/arm/dbg_cp.h", "sim/arm/dbg_rdi.h", 00219 "sim/arm/parent.c", "sim/arm/armsupp.c", "sim/arm/armrdi.c", 00220 "sim/arm/bag.c", "sim/arm/armvirt.c", "sim/arm/main.c", "sim/arm/bag.h", 00221 "sim/arm/communicate.c", "sim/arm/gdbhost.h", "sim/arm/armfpe.h", 00222 "sim/arm/arminit.c", 00223 "sim/common/cgen-fpu.c", "sim/common/cgen-fpu.h", 00224 "sim/common/cgen-accfp.c", 00225 "sim/erc32/sis.h", "sim/erc32/erc32.c", "sim/erc32/func.c", 00226 "sim/erc32/float.c", "sim/erc32/interf.c", "sim/erc32/sis.c", 00227 "sim/erc32/exec.c", 00228 "sim/mips/m16run.c", "sim/mips/sim-main.c", 00229 "sim/moxie/moxie-gdb.dts", 00230 # Not a single file in sim/ppc/ appears to be copyright FSF :-(. 00231 "sim/ppc/filter.h", "sim/ppc/gen-support.h", "sim/ppc/ld-insn.h", 00232 "sim/ppc/hw_sem.c", "sim/ppc/hw_disk.c", "sim/ppc/idecode_branch.h", 00233 "sim/ppc/sim-endian.h", "sim/ppc/table.c", "sim/ppc/hw_core.c", 00234 "sim/ppc/gen-support.c", "sim/ppc/gen-semantics.h", "sim/ppc/cpu.h", 00235 "sim/ppc/sim_callbacks.h", "sim/ppc/RUN", "sim/ppc/Makefile.in", 00236 "sim/ppc/emul_chirp.c", "sim/ppc/hw_nvram.c", "sim/ppc/dc-test.01", 00237 "sim/ppc/hw_phb.c", "sim/ppc/hw_eeprom.c", "sim/ppc/bits.h", 00238 "sim/ppc/hw_vm.c", "sim/ppc/cap.h", "sim/ppc/os_emul.h", 00239 "sim/ppc/options.h", "sim/ppc/gen-idecode.c", "sim/ppc/filter.c", 00240 "sim/ppc/corefile-n.h", "sim/ppc/std-config.h", "sim/ppc/ld-decode.h", 00241 "sim/ppc/filter_filename.h", "sim/ppc/hw_shm.c", 00242 "sim/ppc/pk_disklabel.c", "sim/ppc/dc-simple", "sim/ppc/misc.h", 00243 "sim/ppc/device_table.h", "sim/ppc/ld-insn.c", "sim/ppc/inline.c", 00244 "sim/ppc/emul_bugapi.h", "sim/ppc/hw_cpu.h", "sim/ppc/debug.h", 00245 "sim/ppc/hw_ide.c", "sim/ppc/debug.c", "sim/ppc/gen-itable.h", 00246 "sim/ppc/interrupts.c", "sim/ppc/hw_glue.c", "sim/ppc/emul_unix.c", 00247 "sim/ppc/sim_calls.c", "sim/ppc/dc-complex", "sim/ppc/ld-cache.c", 00248 "sim/ppc/registers.h", "sim/ppc/dc-test.02", "sim/ppc/options.c", 00249 "sim/ppc/igen.h", "sim/ppc/registers.c", "sim/ppc/device.h", 00250 "sim/ppc/emul_chirp.h", "sim/ppc/hw_register.c", "sim/ppc/hw_init.c", 00251 "sim/ppc/sim-endian-n.h", "sim/ppc/filter_filename.c", 00252 "sim/ppc/bits.c", "sim/ppc/idecode_fields.h", "sim/ppc/hw_memory.c", 00253 "sim/ppc/misc.c", "sim/ppc/double.c", "sim/ppc/psim.h", 00254 "sim/ppc/hw_trace.c", "sim/ppc/emul_netbsd.h", "sim/ppc/psim.c", 00255 "sim/ppc/ppc-instructions", "sim/ppc/tree.h", "sim/ppc/README", 00256 "sim/ppc/gen-icache.h", "sim/ppc/gen-model.h", "sim/ppc/ld-cache.h", 00257 "sim/ppc/mon.c", "sim/ppc/corefile.h", "sim/ppc/vm.c", 00258 "sim/ppc/INSTALL", "sim/ppc/gen-model.c", "sim/ppc/hw_cpu.c", 00259 "sim/ppc/corefile.c", "sim/ppc/hw_opic.c", "sim/ppc/gen-icache.c", 00260 "sim/ppc/events.h", "sim/ppc/os_emul.c", "sim/ppc/emul_generic.c", 00261 "sim/ppc/main.c", "sim/ppc/hw_com.c", "sim/ppc/gen-semantics.c", 00262 "sim/ppc/emul_bugapi.c", "sim/ppc/device.c", "sim/ppc/emul_generic.h", 00263 "sim/ppc/tree.c", "sim/ppc/mon.h", "sim/ppc/interrupts.h", 00264 "sim/ppc/cap.c", "sim/ppc/cpu.c", "sim/ppc/hw_phb.h", 00265 "sim/ppc/device_table.c", "sim/ppc/lf.c", "sim/ppc/lf.c", 00266 "sim/ppc/dc-stupid", "sim/ppc/hw_pal.c", "sim/ppc/ppc-spr-table", 00267 "sim/ppc/emul_unix.h", "sim/ppc/words.h", "sim/ppc/basics.h", 00268 "sim/ppc/hw_htab.c", "sim/ppc/lf.h", "sim/ppc/ld-decode.c", 00269 "sim/ppc/sim-endian.c", "sim/ppc/gen-itable.c", 00270 "sim/ppc/idecode_expression.h", "sim/ppc/table.h", "sim/ppc/dgen.c", 00271 "sim/ppc/events.c", "sim/ppc/gen-idecode.h", "sim/ppc/emul_netbsd.c", 00272 "sim/ppc/igen.c", "sim/ppc/vm_n.h", "sim/ppc/vm.h", 00273 "sim/ppc/hw_iobus.c", "sim/ppc/inline.h", 00274 "sim/testsuite/sim/bfin/s21.s", "sim/testsuite/sim/mips/mips32-dsp2.s", 00275 ) 00276 00277 if __name__ == "__main__": 00278 main() 00279