1#! /usr/bin/env python 2 3"""copyright.py 4 5This script updates most of the files that are not already handled 6by copyright.sh. It must be run from the gdb/ subdirectory of the 7GDB source tree. 8 9""" 10 11import datetime 12import re 13import os 14import os.path 15 16class Comment(object): 17 """A class describing comment. 18 19 ATTRIBUTES 20 start: A string describing how comments are started. 21 stop: A string describing how comments end. If None, then 22 a comment ends at the end of the line. 23 start2: Some files accept more than 1 kind of comment. 24 For those that do, this is the alternative form. 25 For now, it is assumed that if start2 is not None, 26 then stop is None (thus no stop2 attribute). 27 """ 28 def __init__(self, start, stop=None, start2=None, max_lines=30): 29 """The "Copyright" keyword should be within MAX_LINES lines 30 from the start of the file.""" 31 self.start = start 32 self.stop = stop 33 self.start2 = start2 34 self.max_lines = max_lines 35 36# The Comment object for Ada code (and GPR files). 37ADA_COMMENT = Comment(start="--") 38 39THIS_YEAR = str(datetime.date.today().year) 40 41# Files which should not be modified, either because they are 42# generated, non-FSF, or otherwise special (e.g. license text, 43# or test cases which must be sensitive to line numbering). 44EXCLUSION_LIST = ( 45 "COPYING", "COPYING.LIB", "CVS", "configure", "copying.c", "gdbarch.c", 46 "gdbarch.h", "fdl.texi", "gpl.texi", "gdbtk", "gdb.gdbtk", "osf-share", 47 "aclocal.m4", "step-line.inp", "step-line.c", 48 ) 49 50# Files that are too different from the rest to be processed automatically. 51BY_HAND = ['../sim/ppc/psim.texinfo'] 52 53# Files for which we know that they do not have a copyright header. 54# Ideally, this list should be empty (but it may not be possible to 55# add a copyright header in some of them). 56NO_COPYRIGHT = ( 57 # Configure files. We should fix those, one day. 58 "testsuite/gdb.cell/configure.ac", "testsuite/gdb.hp/configure.ac", 59 "testsuite/gdb.hp/gdb.aCC/configure.ac", 60 "testsuite/gdb.hp/gdb.base-hp/configure.ac", 61 "testsuite/gdb.hp/gdb.compat/configure.ac", 62 "testsuite/gdb.hp/gdb.defects/configure.ac", 63 "testsuite/gdb.hp/gdb.objdbg/configure.ac", 64 "testsuite/gdb.stabs/configure.ac", 65 "../sim/arm/configure.ac", "../sim/avr/configure.ac", 66 "../sim/common/configure.ac", "../sim/configure.ac", 67 "../sim/cr16/configure.ac", "../sim/cris/configure.ac", 68 "../sim/d10v/configure.ac", "../sim/erc32/configure.ac", 69 "../sim/frv/configure.ac", "../sim/h8300/configure.ac", 70 "../sim/igen/configure.ac", "../sim/iq2000/configure.ac", 71 "../sim/lm32/configure.ac", "../sim/m32r/configure.ac", 72 "../sim/m68hc11/configure.ac", "../sim/mcore/configure.ac", 73 "../sim/microblaze/configure.ac", "../sim/mips/configure.ac", 74 "../sim/mn10300/configure.ac", "../sim/moxie/configure.ac", 75 "../sim/ppc/configure.ac", "../sim/sh/configure.ac", 76 "../sim/sh64/configure.ac", "../sim/testsuite/configure.ac", 77 "../sim/testsuite/d10v-elf/configure.ac", 78 "../sim/testsuite/frv-elf/configure.ac", 79 "../sim/testsuite/m32r-elf/configure.ac", 80 "../sim/testsuite/mips64el-elf/configure.ac", "../sim/v850/configure.ac", 81 # Assembly files. It's not certain that we can add a copyright 82 # header in a way that works for all platforms supported by the 83 # testcase... 84 "testsuite/gdb.arch/pa-nullify.s", "testsuite/gdb.arch/pa64-nullify.s", 85 "testsuite/gdb.asm/asmsrc1.s", "testsuite/gdb.asm/asmsrc2.s", 86 "testsuite/gdb.disasm/am33.s", "testsuite/gdb.disasm/h8300s.s", 87 "testsuite/gdb.disasm/hppa.s", "testsuite/gdb.disasm/mn10200.s", 88 "testsuite/gdb.disasm/mn10300.s", "testsuite/gdb.disasm/sh3.s", 89 "testsuite/gdb.disasm/t01_mov.s", "testsuite/gdb.disasm/t02_mova.s", 90 "testsuite/gdb.disasm/t03_add.s", "testsuite/gdb.disasm/t04_sub.s", 91 "testsuite/gdb.disasm/t05_cmp.s", "testsuite/gdb.disasm/t06_ari2.s", 92 "testsuite/gdb.disasm/t07_ari3.s", "testsuite/gdb.disasm/t08_or.s", 93 "testsuite/gdb.disasm/t09_xor.s", "testsuite/gdb.disasm/t10_and.s", 94 "testsuite/gdb.disasm/t11_logs.s", "testsuite/gdb.disasm/t12_bit.s", 95 "testsuite/gdb.disasm/t13_otr.s", "testsuite/gdb.hp/gdb.base-hp/reg-pa64.s", 96 "testsuite/gdb.hp/gdb.base-hp/reg.s", 97 "../sim/testsuite/d10v-elf/exit47.s", 98 "../sim/testsuite/d10v-elf/hello.s", 99 "../sim/testsuite/d10v-elf/loop.s", 100 "../sim/testsuite/d10v-elf/t-ae-ld-d.s", 101 "../sim/testsuite/d10v-elf/t-ae-ld-i.s", 102 "../sim/testsuite/d10v-elf/t-ae-ld-id.s", 103 "../sim/testsuite/d10v-elf/t-ae-ld-im.s", 104 "../sim/testsuite/d10v-elf/t-ae-ld-ip.s", 105 "../sim/testsuite/d10v-elf/t-ae-ld2w-d.s", 106 "../sim/testsuite/d10v-elf/t-ae-ld2w-i.s", 107 "../sim/testsuite/d10v-elf/t-ae-ld2w-id.s", 108 "../sim/testsuite/d10v-elf/t-ae-ld2w-im.s", 109 "../sim/testsuite/d10v-elf/t-ae-ld2w-ip.s", 110 "../sim/testsuite/d10v-elf/t-ae-st-d.s", 111 "../sim/testsuite/d10v-elf/t-ae-st-i.s", 112 "../sim/testsuite/d10v-elf/t-ae-st-id.s", 113 "../sim/testsuite/d10v-elf/t-ae-st-im.s", 114 "../sim/testsuite/d10v-elf/t-ae-st-ip.s", 115 "../sim/testsuite/d10v-elf/t-ae-st-is.s", 116 "../sim/testsuite/d10v-elf/t-ae-st2w-d.s", 117 "../sim/testsuite/d10v-elf/t-ae-st2w-i.s", 118 "../sim/testsuite/d10v-elf/t-ae-st2w-id.s", 119 "../sim/testsuite/d10v-elf/t-ae-st2w-im.s", 120 "../sim/testsuite/d10v-elf/t-ae-st2w-ip.s", 121 "../sim/testsuite/d10v-elf/t-ae-st2w-is.s", 122 "../sim/testsuite/d10v-elf/t-dbt.s", 123 "../sim/testsuite/d10v-elf/t-ld-st.s", 124 "../sim/testsuite/d10v-elf/t-mac.s", 125 "../sim/testsuite/d10v-elf/t-mod-ld-pre.s", 126 "../sim/testsuite/d10v-elf/t-msbu.s", 127 "../sim/testsuite/d10v-elf/t-mulxu.s", 128 "../sim/testsuite/d10v-elf/t-mvtac.s", 129 "../sim/testsuite/d10v-elf/t-mvtc.s", 130 "../sim/testsuite/d10v-elf/t-rac.s", 131 "../sim/testsuite/d10v-elf/t-rachi.s", 132 "../sim/testsuite/d10v-elf/t-rdt.s", 133 "../sim/testsuite/d10v-elf/t-rep.s", 134 "../sim/testsuite/d10v-elf/t-rie-xx.s", 135 "../sim/testsuite/d10v-elf/t-rte.s", 136 "../sim/testsuite/d10v-elf/t-sac.s", 137 "../sim/testsuite/d10v-elf/t-sachi.s", 138 "../sim/testsuite/d10v-elf/t-sadd.s", 139 "../sim/testsuite/d10v-elf/t-slae.s", 140 "../sim/testsuite/d10v-elf/t-sp.s", 141 "../sim/testsuite/d10v-elf/t-sub.s", 142 "../sim/testsuite/d10v-elf/t-sub2w.s", 143 "../sim/testsuite/d10v-elf/t-subi.s", 144 "../sim/testsuite/d10v-elf/t-trap.s", 145 "../sim/testsuite/frv-elf/cache.s", 146 "../sim/testsuite/frv-elf/exit47.s", 147 "../sim/testsuite/frv-elf/grloop.s", 148 "../sim/testsuite/frv-elf/hello.s", 149 "../sim/testsuite/frv-elf/loop.s", 150 "../sim/testsuite/m32r-elf/exit47.s", 151 "../sim/testsuite/m32r-elf/hello.s", 152 "../sim/testsuite/m32r-elf/loop.s", 153 "../sim/testsuite/sim/cris/hw/rv-n-cris/quit.s", 154 "../sim/testsuite/sim/h8300/addb.s", 155 "../sim/testsuite/sim/h8300/addl.s", 156 "../sim/testsuite/sim/h8300/adds.s", 157 "../sim/testsuite/sim/h8300/addw.s", 158 "../sim/testsuite/sim/h8300/addx.s", 159 "../sim/testsuite/sim/h8300/andb.s", 160 "../sim/testsuite/sim/h8300/andl.s", 161 "../sim/testsuite/sim/h8300/andw.s", 162 "../sim/testsuite/sim/h8300/band.s", 163 "../sim/testsuite/sim/h8300/bfld.s", 164 "../sim/testsuite/sim/h8300/biand.s", 165 "../sim/testsuite/sim/h8300/bra.s", 166 "../sim/testsuite/sim/h8300/brabc.s", 167 "../sim/testsuite/sim/h8300/bset.s", 168 "../sim/testsuite/sim/h8300/cmpb.s", 169 "../sim/testsuite/sim/h8300/cmpl.s", 170 "../sim/testsuite/sim/h8300/cmpw.s", 171 "../sim/testsuite/sim/h8300/daa.s", 172 "../sim/testsuite/sim/h8300/das.s", 173 "../sim/testsuite/sim/h8300/dec.s", 174 "../sim/testsuite/sim/h8300/div.s", 175 "../sim/testsuite/sim/h8300/extl.s", 176 "../sim/testsuite/sim/h8300/extw.s", 177 "../sim/testsuite/sim/h8300/inc.s", 178 "../sim/testsuite/sim/h8300/jmp.s", 179 "../sim/testsuite/sim/h8300/ldc.s", 180 "../sim/testsuite/sim/h8300/ldm.s", 181 "../sim/testsuite/sim/h8300/mac.s", 182 "../sim/testsuite/sim/h8300/mova.s", 183 "../sim/testsuite/sim/h8300/movb.s", 184 "../sim/testsuite/sim/h8300/movl.s", 185 "../sim/testsuite/sim/h8300/movmd.s", 186 "../sim/testsuite/sim/h8300/movsd.s", 187 "../sim/testsuite/sim/h8300/movw.s", 188 "../sim/testsuite/sim/h8300/mul.s", 189 "../sim/testsuite/sim/h8300/neg.s", 190 "../sim/testsuite/sim/h8300/nop.s", 191 "../sim/testsuite/sim/h8300/not.s", 192 "../sim/testsuite/sim/h8300/orb.s", 193 "../sim/testsuite/sim/h8300/orl.s", 194 "../sim/testsuite/sim/h8300/orw.s", 195 "../sim/testsuite/sim/h8300/rotl.s", 196 "../sim/testsuite/sim/h8300/rotr.s", 197 "../sim/testsuite/sim/h8300/rotxl.s", 198 "../sim/testsuite/sim/h8300/rotxr.s", 199 "../sim/testsuite/sim/h8300/shal.s", 200 "../sim/testsuite/sim/h8300/shar.s", 201 "../sim/testsuite/sim/h8300/shll.s", 202 "../sim/testsuite/sim/h8300/shlr.s", 203 "../sim/testsuite/sim/h8300/stack.s", 204 "../sim/testsuite/sim/h8300/stc.s", 205 "../sim/testsuite/sim/h8300/subb.s", 206 "../sim/testsuite/sim/h8300/subl.s", 207 "../sim/testsuite/sim/h8300/subs.s", 208 "../sim/testsuite/sim/h8300/subw.s", 209 "../sim/testsuite/sim/h8300/subx.s", 210 "../sim/testsuite/sim/h8300/tas.s", 211 "../sim/testsuite/sim/h8300/xorb.s", 212 "../sim/testsuite/sim/h8300/xorl.s", 213 "../sim/testsuite/sim/h8300/xorw.s", 214 "../sim/testsuite/sim/mips/fpu64-ps-sb1.s", 215 "../sim/testsuite/sim/mips/fpu64-ps.s", 216 "../sim/testsuite/sim/mips/hilo-hazard-1.s", 217 "../sim/testsuite/sim/mips/hilo-hazard-2.s", 218 "../sim/testsuite/sim/mips/hilo-hazard-3.s", 219 "../sim/testsuite/sim/mips/mdmx-ob-sb1.s", 220 "../sim/testsuite/sim/mips/mdmx-ob.s", 221 "../sim/testsuite/sim/mips/mips32-dsp.s", 222 "../sim/testsuite/sim/mips/mips32-dsp2.s", 223 "../sim/testsuite/sim/mips/sanity.s", 224 "../sim/testsuite/sim/sh/add.s", 225 "../sim/testsuite/sim/sh/and.s", 226 "../sim/testsuite/sim/sh/bandor.s", 227 "../sim/testsuite/sim/sh/bandornot.s", 228 "../sim/testsuite/sim/sh/bclr.s", 229 "../sim/testsuite/sim/sh/bld.s", 230 "../sim/testsuite/sim/sh/bldnot.s", 231 "../sim/testsuite/sim/sh/bset.s", 232 "../sim/testsuite/sim/sh/bst.s", 233 "../sim/testsuite/sim/sh/bxor.s", 234 "../sim/testsuite/sim/sh/clip.s", 235 "../sim/testsuite/sim/sh/div.s", 236 "../sim/testsuite/sim/sh/dmxy.s", 237 "../sim/testsuite/sim/sh/fabs.s", 238 "../sim/testsuite/sim/sh/fadd.s", 239 "../sim/testsuite/sim/sh/fail.s", 240 "../sim/testsuite/sim/sh/fcmpeq.s", 241 "../sim/testsuite/sim/sh/fcmpgt.s", 242 "../sim/testsuite/sim/sh/fcnvds.s", 243 "../sim/testsuite/sim/sh/fcnvsd.s", 244 "../sim/testsuite/sim/sh/fdiv.s", 245 "../sim/testsuite/sim/sh/fipr.s", 246 "../sim/testsuite/sim/sh/fldi0.s", 247 "../sim/testsuite/sim/sh/fldi1.s", 248 "../sim/testsuite/sim/sh/flds.s", 249 "../sim/testsuite/sim/sh/float.s", 250 "../sim/testsuite/sim/sh/fmac.s", 251 "../sim/testsuite/sim/sh/fmov.s", 252 "../sim/testsuite/sim/sh/fmul.s", 253 "../sim/testsuite/sim/sh/fneg.s", 254 "../sim/testsuite/sim/sh/fpchg.s", 255 "../sim/testsuite/sim/sh/frchg.s", 256 "../sim/testsuite/sim/sh/fsca.s", 257 "../sim/testsuite/sim/sh/fschg.s", 258 "../sim/testsuite/sim/sh/fsqrt.s", 259 "../sim/testsuite/sim/sh/fsrra.s", 260 "../sim/testsuite/sim/sh/fsub.s", 261 "../sim/testsuite/sim/sh/ftrc.s", 262 "../sim/testsuite/sim/sh/ldrc.s", 263 "../sim/testsuite/sim/sh/loop.s", 264 "../sim/testsuite/sim/sh/macl.s", 265 "../sim/testsuite/sim/sh/macw.s", 266 "../sim/testsuite/sim/sh/mov.s", 267 "../sim/testsuite/sim/sh/movi.s", 268 "../sim/testsuite/sim/sh/movli.s", 269 "../sim/testsuite/sim/sh/movua.s", 270 "../sim/testsuite/sim/sh/movxy.s", 271 "../sim/testsuite/sim/sh/mulr.s", 272 "../sim/testsuite/sim/sh/pabs.s", 273 "../sim/testsuite/sim/sh/padd.s", 274 "../sim/testsuite/sim/sh/paddc.s", 275 "../sim/testsuite/sim/sh/pand.s", 276 "../sim/testsuite/sim/sh/pass.s", 277 "../sim/testsuite/sim/sh/pclr.s", 278 "../sim/testsuite/sim/sh/pdec.s", 279 "../sim/testsuite/sim/sh/pdmsb.s", 280 "../sim/testsuite/sim/sh/pinc.s", 281 "../sim/testsuite/sim/sh/pmuls.s", 282 "../sim/testsuite/sim/sh/prnd.s", 283 "../sim/testsuite/sim/sh/pshai.s", 284 "../sim/testsuite/sim/sh/pshar.s", 285 "../sim/testsuite/sim/sh/pshli.s", 286 "../sim/testsuite/sim/sh/pshlr.s", 287 "../sim/testsuite/sim/sh/psub.s", 288 "../sim/testsuite/sim/sh/pswap.s", 289 "../sim/testsuite/sim/sh/pushpop.s", 290 "../sim/testsuite/sim/sh/resbank.s", 291 "../sim/testsuite/sim/sh/sett.s", 292 "../sim/testsuite/sim/sh/shll.s", 293 "../sim/testsuite/sim/sh/shll16.s", 294 "../sim/testsuite/sim/sh/shll2.s", 295 "../sim/testsuite/sim/sh/shll8.s", 296 "../sim/testsuite/sim/sh/shlr.s", 297 "../sim/testsuite/sim/sh/shlr16.s", 298 "../sim/testsuite/sim/sh/shlr2.s", 299 "../sim/testsuite/sim/sh/shlr8.s", 300 "../sim/testsuite/sim/sh/swap.s", 301 "../sim/testsuite/sim/sh64/misc/fr-dr.s", 302 # .inc files. These are usually assembly or C files... 303 "testsuite/gdb.asm/alpha.inc", 304 "testsuite/gdb.asm/arm.inc", 305 "testsuite/gdb.asm/common.inc", 306 "testsuite/gdb.asm/empty.inc", 307 "testsuite/gdb.asm/frv.inc", 308 "testsuite/gdb.asm/h8300.inc", 309 "testsuite/gdb.asm/i386.inc", 310 "testsuite/gdb.asm/ia64.inc", 311 "testsuite/gdb.asm/iq2000.inc", 312 "testsuite/gdb.asm/m32c.inc", 313 "testsuite/gdb.asm/m32r-linux.inc", 314 "testsuite/gdb.asm/m32r.inc", 315 "testsuite/gdb.asm/m68hc11.inc", 316 "testsuite/gdb.asm/m68k.inc", 317 "testsuite/gdb.asm/mips.inc", 318 "testsuite/gdb.asm/netbsd.inc", 319 "testsuite/gdb.asm/openbsd.inc", 320 "testsuite/gdb.asm/pa.inc", 321 "testsuite/gdb.asm/pa64.inc", 322 "testsuite/gdb.asm/powerpc.inc", 323 "testsuite/gdb.asm/powerpc64.inc", 324 "testsuite/gdb.asm/s390.inc", 325 "testsuite/gdb.asm/s390x.inc", 326 "testsuite/gdb.asm/sh.inc", 327 "testsuite/gdb.asm/sparc.inc", 328 "testsuite/gdb.asm/sparc64.inc", 329 "testsuite/gdb.asm/spu.inc", 330 "testsuite/gdb.asm/v850.inc", 331 "testsuite/gdb.asm/x86_64.inc", 332 "testsuite/gdb.asm/xstormy16.inc", 333 "../sim/testsuite/sim/arm/iwmmxt/testutils.inc", 334 "../sim/testsuite/sim/arm/testutils.inc", 335 "../sim/testsuite/sim/arm/thumb/testutils.inc", 336 "../sim/testsuite/sim/arm/xscale/testutils.inc", 337 "../sim/testsuite/sim/cr16/testutils.inc", 338 "../sim/testsuite/sim/cris/asm/testutils.inc", 339 "../sim/testsuite/sim/cris/hw/rv-n-cris/testutils.inc", 340 "../sim/testsuite/sim/fr30/testutils.inc", 341 "../sim/testsuite/sim/frv/testutils.inc", 342 "../sim/testsuite/sim/h8300/testutils.inc", 343 "../sim/testsuite/sim/m32r/testutils.inc", 344 "../sim/testsuite/sim/sh/testutils.inc", 345 "../sim/testsuite/sim/sh64/compact/testutils.inc", 346 "../sim/testsuite/sim/sh64/media/testutils.inc", 347 "../sim/testsuite/sim/v850/testutils.inc", 348 ) 349 350# A mapping between file extensions to their associated Comment object. 351# This dictionary also contains a number of exceptions, based on 352# filename. 353COMMENT_MAP = \ 354 {".1" : Comment(start=r'.\"'), 355 ".ac" : Comment(start="dnl", start2="#"), 356 ".ads" : ADA_COMMENT, 357 ".adb" : ADA_COMMENT, 358 ".f" : Comment(start="c"), 359 ".f90" : Comment(start="!"), 360 ".gpr" : ADA_COMMENT, 361 ".inc" : Comment(start="#", start2=";"), 362 ".s" : Comment(start="!"), 363 ".tex" : Comment(start="%"), 364 ".texi" : Comment(start="@c"), 365 ".texinfo" : Comment(start="@c"), 366 367 # Files that use a different way of including the copyright 368 # header... 369 "ada-operator.inc" : Comment(start="/*", stop="*/"), 370 "gdbint.texinfo" : Comment(start='@copying', stop="@end copying"), 371 "annotate.texinfo" : Comment(start='@copying', stop="@end copying", 372 max_lines=50), 373 "stabs.texinfo" : Comment(start='@copying', stop="@end copying"), 374 } 375 376class NotFound(Exception): 377 pass 378 379class AlreadyDone(Exception): 380 pass 381 382def process_header(src, dst, cdescr): 383 """Read from SRC for up to CDESCR.MAX_LINES until we find a copyright 384 notice. If found, then write the entire file, with the copyright 385 noticed updated with the current year added. 386 387 Raises NotFound if the copyright notice could not be found or has 388 some inconsistencies. 389 390 Raises AlreadyDone if the copyright notice already includes the current 391 year. 392 """ 393 line_count = 0 394 # The start-of-comment marker used for this file. Only really useful 395 # in the case where comments ends at the end of the line, as this 396 # allows us to know which comment marker to use when breaking long 397 # lines (in the cases where there are more than one. 398 cdescr_start = "" 399 400 while True: 401 # If we still haven't found a copyright line within a certain 402 # number of lines, then give up. 403 if line_count > cdescr.max_lines: 404 raise NotFound("start of Copyright not found") 405 406 line = src.readline() 407 line_count += 1 408 if not line: 409 raise NotFound("start of Copyright not found (EOF)") 410 411 # Is this a copyright line? If not, then no transformation is 412 # needed. Write it as is, and continue. 413 if not re.search(r"Copyright\b.*\b(199\d|20\d\d)\b", line): 414 dst.write(line) 415 continue 416 417 # If a start-of-comment marker is needed for every line, try to 418 # figure out which one it is that is being used in this file (most 419 # files only accept one, in which case it's easy - but some accept 420 # two or more...). 421 if cdescr.stop is None: 422 stripped_line = line.lstrip() 423 if stripped_line.startswith(cdescr.start): 424 cdescr_start = cdescr.start 425 elif (cdescr.start2 is not None 426 and stripped_line.startswith(cdescr.start2)): 427 cdescr_start = cdescr.start2 428 elif cdescr.start in stripped_line: 429 cdescr_start = cdescr.start 430 elif (cdescr.start2 is not None 431 and cdescr.start2 in stripped_line): 432 cdescr_start = cdescr.start2 433 else: 434 # This can't be a line with a comment, so not the copyright 435 # line we were looking for. Ignore. 436 continue 437 438 comment = line 439 break 440 441 while not re.search(r"Free\s+Software\s+Foundation", comment): 442 line = src.readline() 443 line_count += 1 444 if not line: 445 raise NotFound("Copyright owner not found (EOF)") 446 447 if cdescr.stop is None: 448 # Expect a new comment marker at the start of each line 449 line = line.lstrip() 450 if not line.startswith(cdescr_start): 451 raise NotFound("Copyright owner not found " 452 "(end of comment)") 453 comment += " " + line[len(cdescr_start):] 454 else: 455 if cdescr.stop in comment: 456 raise NotFound("Copyright owner not found " 457 "(end of comment)") 458 comment += line 459 460 # Normalize a bit the copyright string (we preserve the string 461 # up until "Copyright", in order to help preserve any original 462 # alignment. 463 (before, after) = comment.split("Copyright", 1) 464 after = after.replace("\n", " ") 465 after = re.sub("\s+", " ", after) 466 after = after.rstrip() 467 468 # If the copyright year has already been added, the nothing else 469 # to do. 470 if THIS_YEAR in after: 471 raise AlreadyDone 472 473 m = re.match("(.*[0-9]+)(.*)", after) 474 if m is None: 475 raise NotFound("Internal error - cannot split copyright line: " 476 "`%s'" % comment) 477 478 # Reconstruct the comment line 479 comment = before + "Copyright" + m.group(1) + ', %s' % THIS_YEAR 480 owner_part = m.group(2).lstrip() 481 482 # Max comment len... 483 max_len = 76 484 485 # If we have to break the copyright line into multiple lines, 486 # we want to align all the lines on the "Copyright" keyword. 487 # Create a small "indent" string that we can use for that. 488 if cdescr.stop is None: 489 # The comment marker is needed on every line, so put it at the 490 # start of our "indent" string. 491 indent = cdescr_start + ' ' * (len(before) - len(cdescr_start)) 492 else: 493 indent = ' ' * len(before) 494 495 # If the line is too long... 496 while len(comment) > max_len: 497 # Split the line at the first space before max_len. 498 space_index = comment[0:max_len].rfind(' ') 499 if space_index < 0: # No space in the first max_len characters??? 500 # Split at the first space, then... 501 space_index = comment.find(' ') 502 if space_index < 0: 503 # Still no space found. This is extremely unlikely, but 504 # just pretend there is one at the end of the string. 505 space_index = len(comment) 506 507 # Write the first part of the string up until the space 508 # we selected to break our line. 509 dst.write(comment[:space_index] + '\n') 510 511 # Strip the part of comment that we have finished printing. 512 if space_index < len(comment): 513 comment = comment[space_index + 1:] 514 else: 515 comment = "" 516 517 # Prepend the "indent" string to make sure that we remain 518 # aligned on the "Copyright" word. 519 comment = indent + comment 520 521 # And finally, write the rest of the last line... We want to write 522 # "Free Software Foundation, Inc" on the same line, so handle this 523 # with extra care. 524 dst.write(comment) 525 if len(comment) + 1 + len (owner_part) > max_len: 526 dst.write('\n' + indent) 527 else: 528 dst.write(' ') 529 dst.write(owner_part + '\n') 530 531def comment_for_filename(filename): 532 """Return the Comment object that best describes the given file. 533 This a smart lookup of the COMMENT_MAP dictionary where we check 534 for filename-based exceptions first, before looking up the comment 535 by filename extension. """ 536 # First, consult the COMMENT_MAP using the filename, in case this 537 # file needs special treatment. 538 basename = os.path.basename(filename) 539 if basename in COMMENT_MAP: 540 return COMMENT_MAP[basename] 541 # Not a special file. Check the file extension. 542 ext = os.path.splitext(filename)[1] 543 if ext in COMMENT_MAP: 544 return COMMENT_MAP[ext] 545 # Not a know extension either, return None. 546 return None 547 548def process_file(filename): 549 """Processes the given file. 550 """ 551 cdescr = comment_for_filename(filename) 552 if cdescr is None: 553 # Either no filename extension, or not an extension that we 554 # know how to handle. 555 return 556 557 dst_filename = filename + '.new' 558 src = open(filename) 559 dst = open(dst_filename, 'w') 560 try: 561 process_header(src, dst, cdescr) 562 except AlreadyDone: 563 print "+++ Already up to date: `%s'." % filename 564 dst.close() 565 os.unlink(dst_filename) 566 if filename in NO_COPYRIGHT: 567 # We expect the search for a copyright header to fail, and 568 # yet we found one... 569 print "Warning: `%s' should not be in NO_COPYRIGHT" % filename 570 return 571 except NotFound as inst: 572 dst.close() 573 os.unlink(dst_filename) 574 if not filename in NO_COPYRIGHT: 575 print "*** \033[31m%s\033[0m: %s" % (filename, inst) 576 return 577 578 if filename in NO_COPYRIGHT: 579 # We expect the search for a copyright header to fail, and 580 # yet we found one... 581 print "Warning: `%s' should not be in NO_COPYRIGHT" % filename 582 583 for line in src: 584 dst.write(line) 585 src.close() 586 dst.close() 587 os.rename(dst_filename, filename) 588 589if __name__ == "__main__": 590 if not os.path.isfile("doc/gdb.texinfo"): 591 print "Error: This script must be called from the gdb directory." 592 for gdb_dir in ('.', '../sim', '../include/gdb'): 593 for root, dirs, files in os.walk(gdb_dir): 594 for filename in files: 595 fullpath = os.path.join(root, filename) 596 if fullpath.startswith('./'): 597 fullpath = fullpath[2:] 598 if filename not in EXCLUSION_LIST and fullpath not in BY_HAND: 599 # Paths that start with './' are ugly, so strip that. 600 # This also allows us to omit them in the NO_COPYRIGHT 601 # list... 602 process_file(fullpath) 603 print 604 print "\033[32mREMINDER: The following files must be updated by hand." \ 605 "\033[0m" 606 for filename in BY_HAND: 607 print " ", filename 608 609