]> git.proxmox.com Git - mirror_frr.git/blame - python/firstheader.py
*: auto-convert to SPDX License IDs
[mirror_frr.git] / python / firstheader.py
CommitLineData
acddc0ed 1# SPDX-License-Identifier: GPL-2.0-or-later
980ab2de
DL
2# check that the first header included in C files is either
3# zebra.h or config.h
4#
1f8031f7 5# Copyright (C) 2020 David Lamparter for NetDEF, Inc.
980ab2de 6
1f8031f7
DL
7import sys
8import os
9import re
10import subprocess
11import argparse
12
13argp = argparse.ArgumentParser(description="include fixer")
14argp.add_argument("--autofix", action="store_const", const=True)
15argp.add_argument("--warn-empty", action="store_const", const=True)
16argp.add_argument("--pipe", action="store_const", const=True)
980ab2de
DL
17
18include_re = re.compile('^#\s*include\s+["<]([^ ">]+)[">]', re.M)
19
1f8031f7
DL
20ignore = [
21 lambda fn: fn.startswith("tools/"),
22 lambda fn: fn
23 in [
24 "lib/elf_py.c",
25 ],
26]
27
28
29def run(args):
30 out = []
31
32 files = subprocess.check_output(["git", "ls-files"]).decode("ASCII")
33 for fn in files.splitlines():
34 if not fn.endswith(".c"):
35 continue
36 if max([i(fn) for i in ignore]):
37 continue
38
39 with open(fn, "r") as fd:
40 data = fd.read()
980ab2de 41
980ab2de
DL
42 m = include_re.search(data)
43 if m is None:
1f8031f7
DL
44 if args.warn_empty:
45 sys.stderr.write("no #include in %s?\n" % (fn))
980ab2de 46 continue
701a0192 47 if m.group(1) in ["config.h", "zebra.h", "lib/zebra.h"]:
980ab2de 48 continue
980ab2de 49
1f8031f7
DL
50 if args.autofix:
51 sys.stderr.write("%s: %s - fixing\n" % (fn, m.group(0)))
52 if fn.startswith("pceplib/"):
53 insert = '#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n'
54 else:
55 insert = "#include <zebra.h>\n\n"
56
57 pos = m.span()[0]
58
59 data = data[:pos] + insert + data[pos:]
60 with open(fn + ".new", "w") as fd:
61 fd.write(data)
62 os.rename(fn + ".new", fn)
63 else:
64 sys.stderr.write("%s: %s\n" % (fn, m.group(0)))
65 out.append(fn)
66
67 if len(out):
68 if args.pipe:
69 # for "vim `firstheader.py`"
70 print("\n".join(out))
71 return 1
72 return 0
73
74
75if __name__ == "__main__":
76 args = argp.parse_args()
77 sys.exit(run(args))