Commit | Line | Data |
---|---|---|
e9bdf92c JB |
1 | #! /usr/bin/env python |
2 | ||
3 | """copyright.py | |
4 | ||
5 | This script updates most of the files that are not already handled | |
6 | by copyright.sh. It must be run from the gdb/ subdirectory of the | |
7 | GDB source tree. | |
8 | ||
9 | """ | |
10 | ||
11 | import datetime | |
12 | import re | |
13 | import os | |
14 | import os.path | |
15 | ||
16 | class 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). | |
37 | ADA_COMMENT = Comment(start="--") | |
38 | ||
39 | THIS_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). | |
44 | EXCLUSION_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. | |
51 | BY_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). | |
56 | NO_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. | |
353 | COMMENT_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 | ||
376 | class NotFound(Exception): | |
377 | pass | |
378 | ||
379 | class AlreadyDone(Exception): | |
380 | pass | |
381 | ||
382 | def 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 | ||
531 | def 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 | ||
548 | def 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 | ||
589 | if __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 | ||
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 |