File: apply_cpplint_header_guard.py

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (71 lines) | stat: -rwxr-xr-x 2,462 bytes parent folder | download
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
#!/usr/bin/env python3
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Applies cpplint build/header_guard recommendations.

Reads cpplint build/header_guard recommendations from stdin and applies them.

Run cpplint for a single header:
cpplint.py --filter=-,+build/header_guard foo.h 2>&1 | grep build/header_guard

Run cpplint for all headers in dir foo in parallel:
find foo -name '*.h' | \
    xargs parallel cpplint.py --filter=-,+build/header_guard -- 2>&1 | \
    grep build/header_guard
"""

import sys

IFNDEF_MSG = '  #ifndef header guard has wrong style, please use'
ENDIF_MSG_START = '  #endif line should be "'
ENDIF_MSG_END = '"  [build/header_guard] [5]'
NO_GUARD_MSG = '  No #ifndef header guard found, suggested CPP variable is'


def process_cpplint_recommendations(cpplint_data):
  root = sys.argv[1] if len(sys.argv) > 1 else ''
  root = "_".join(root.upper().strip(r'[/]+').split('/'))+"_"
  for entry in cpplint_data:
    entry = entry.split(':')
    header = entry[0]
    line = entry[1]
    index = int(line) - 1
    msg = entry[2].rstrip()
    if msg == IFNDEF_MSG:
      assert len(entry) == 4

      with open(header, 'rb') as f:
        content = f.readlines()

      if not content[index + 1].startswith(b'#define '):
        raise Exception('Missing #define: %s:%d' % (header, index + 2))

      guard = entry[3].split(' ')[1]
      guard = guard.replace(root, '') if len(root) > 1 else guard
      content[index] = ('#ifndef %s\n' % guard).encode('utf-8')
      # Since cpplint does not print messages for the #define line, just
      # blindly overwrite the #define that was here.
      content[index + 1] = ('#define %s\n' % guard).encode('utf-8')
    elif msg.startswith(ENDIF_MSG_START):
      assert len(entry) == 3
      assert msg.endswith(ENDIF_MSG_END)

      with open(header, 'rb') as f:
        content = f.readlines()
      endif = msg[len(ENDIF_MSG_START):-len(ENDIF_MSG_END)]
      endif = endif.replace(root, '') if len(root) > 1 else endif
      content[index] = ('%s\n' % endif).encode('utf-8')
    elif msg == NO_GUARD_MSG:
      assert index == -1
      continue
    else:
      raise Exception('Unknown cpplint message: %s for %s:%s' %
                      (msg, header, line))

    with open(header, 'wb') as f:
      f.writelines(content)


if __name__ == '__main__':
  process_cpplint_recommendations(sys.stdin)