2 # Copyright 2021 The Chromium Authors
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5 """Applies cpplint build/header_guard recommendations.
7 Reads cpplint build/header_guard recommendations from stdin and applies them.
9 Run cpplint for a single header:
10 cpplint.py --filter=-,+build/header_guard foo.h 2>&1 | grep build/header_guard
12 Run cpplint for all headers in dir foo in parallel:
13 find foo -name '*.h' | \
14 xargs parallel cpplint.py --filter=-,+build/header_guard -- 2>&1 | \
15 grep build/header_guard
20 IFNDEF_MSG = ' #ifndef header guard has wrong style, please use'
21 ENDIF_MSG_START = ' #endif line should be "'
22 ENDIF_MSG_END = '" [build/header_guard] [5]'
23 NO_GUARD_MSG = ' No #ifndef header guard found, suggested CPP variable is'
26 def process_cpplint_recommendations(cpplint_data):
27 root = sys.argv[1] if len(sys.argv) > 1 else ''
28 root = "_".join(root.upper().strip(r'[/]+').split('/'))+"_"
29 for entry in cpplint_data:
30 entry = entry.split(':')
34 msg = entry[2].rstrip()
36 assert len(entry) == 4
38 with open(header, 'rb') as f:
39 content = f.readlines()
41 if not content[index + 1].startswith(b'#define '):
42 raise Exception('Missing #define: %s:%d' % (header, index + 2))
44 guard = entry[3].split(' ')[1]
45 guard = guard.replace(root, '') if len(root) > 1 else guard
46 content[index] = ('#ifndef %s\n' % guard).encode('utf-8')
47 # Since cpplint does not print messages for the #define line, just
48 # blindly overwrite the #define that was here.
49 content[index + 1] = ('#define %s\n' % guard).encode('utf-8')
50 elif msg.startswith(ENDIF_MSG_START):
51 assert len(entry) == 3
52 assert msg.endswith(ENDIF_MSG_END)
54 with open(header, 'rb') as f:
55 content = f.readlines()
56 endif = msg[len(ENDIF_MSG_START):-len(ENDIF_MSG_END)]
57 endif = endif.replace(root, '') if len(root) > 1 else endif
58 content[index] = ('%s\n' % endif).encode('utf-8')
59 elif msg == NO_GUARD_MSG:
63 raise Exception('Unknown cpplint message: %s for %s:%s' %
66 with open(header, 'wb') as f:
70 if __name__ == '__main__':
71 process_cpplint_recommendations(sys.stdin)