[PDNCF] Python 3.12 compatibility
[platform/framework/web/chromium-efl.git] / tools / apply_cpplint_header_guard.py
1 #!/usr/bin/env python3
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.
6
7 Reads cpplint build/header_guard recommendations from stdin and applies them.
8
9 Run cpplint for a single header:
10 cpplint.py --filter=-,+build/header_guard foo.h 2>&1 | grep build/header_guard
11
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
16 """
17
18 import sys
19
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'
24
25
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(':')
31     header = entry[0]
32     line = entry[1]
33     index = int(line) - 1
34     msg = entry[2].rstrip()
35     if msg == IFNDEF_MSG:
36       assert len(entry) == 4
37
38       with open(header, 'rb') as f:
39         content = f.readlines()
40
41       if not content[index + 1].startswith(b'#define '):
42         raise Exception('Missing #define: %s:%d' % (header, index + 2))
43
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)
53
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:
60       assert index == -1
61       continue
62     else:
63       raise Exception('Unknown cpplint message: %s for %s:%s' %
64                       (msg, header, line))
65
66     with open(header, 'wb') as f:
67       f.writelines(content)
68
69
70 if __name__ == '__main__':
71   process_cpplint_recommendations(sys.stdin)