forked from lowRISC/opentitan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fix_include_guard.py
executable file
·81 lines (64 loc) · 2.77 KB
/
fix_include_guard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
# fix_include_guard.py script takes any number of C or C++ header files as
# input, and formats their include guards to conform to the style mandated
# by Google C++. See
# https://google.github.io/styleguide/cppguide.html#The__define_Guard
#
# clang-format does not, unfortunately, have support for automatically
# generating the correct include guards; hence the existence of this script.
#
# This script will write the names of all affected files to stdout; if no such
# output is present, all files have the correct guards. This script is
# idempotent.
import argparse
import os
import sys
import re
from pathlib import Path
PROJECT_NAME = "OPENTITAN"
# This file is $REPO_TOP/util/fix_include_guard.py, so it takes two parent()
# calls to get back to the top.
REPO_TOP = Path(__file__).resolve().parent.parent
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--dry-run',
action='store_true',
help='report writes which would have happened')
parser.add_argument(
'headers',
type=str,
nargs='+',
help='headers to fix guards for')
args = parser.parse_args()
total_fixes = 0
for header_path in args.headers:
header = Path(header_path).resolve().relative_to(REPO_TOP)
if header.suffix != '.h' or 'vendor' in header.parts:
continue
uppercase_dir = re.sub(r'[^\w]', '_', str(header.parent)).upper()
uppercase_stem = re.sub(r'[^\w]', '_', str(header.stem)).upper()
guard = '%s_%s_%s_H_' % (PROJECT_NAME, uppercase_dir, uppercase_stem)
header_text = header.read_text()
header_original = header_text
# Find the old guard name, which will be the first #ifndef in the file.
old_guard = re.search(r'#ifndef +(\w+)', header_text).group(1)
# Fix the guards at the top, which are guaranteed to be there.
header_text = re.sub('#(ifndef|define) +%s' % (old_guard, ),
r'#\1 %s' % (guard, ), header_text)
# Fix up the endif. Since this is the last thing in the file, and it
# might be missing the comment, we just truncate the file, and add on
# the required guard end.
header_text = header_text[:header_text.rindex('#endif')]
header_text += "#endif // %s\n" % (guard, )
if header_text != header_original:
print('Fixing header: "%s"' % (header, ), file=sys.stdout)
total_fixes += 1
if not args.dry_run:
header.write_text(header_text)
print('Fixed %d files.' % (total_fixes, ), file=sys.stderr)
if __name__ == '__main__':
main()