xref: /aosp_15_r20/external/perfetto/tools/fix_include_guards (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker#
4*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker#
8*6dbdd20aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker#
10*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker
16*6dbdd20aSAndroid Build Coastguard Workerfrom __future__ import print_function
17*6dbdd20aSAndroid Build Coastguard Worker
18*6dbdd20aSAndroid Build Coastguard Workerimport os
19*6dbdd20aSAndroid Build Coastguard Workerimport re
20*6dbdd20aSAndroid Build Coastguard Workerimport sys
21*6dbdd20aSAndroid Build Coastguard Worker
22*6dbdd20aSAndroid Build Coastguard Workerfrom codecs import open
23*6dbdd20aSAndroid Build Coastguard Workerfrom compat import xrange
24*6dbdd20aSAndroid Build Coastguard Worker
25*6dbdd20aSAndroid Build Coastguard WorkerEXCLUDED_FILES = [
26*6dbdd20aSAndroid Build Coastguard Worker  'src/trace_processor/perfetto_sql/preprocessor/preprocessor_grammar.h',
27*6dbdd20aSAndroid Build Coastguard Worker  'src/trace_processor/perfetto_sql/grammar/perfettosql_grammar.h',
28*6dbdd20aSAndroid Build Coastguard Worker]
29*6dbdd20aSAndroid Build Coastguard Worker
30*6dbdd20aSAndroid Build Coastguard Worker
31*6dbdd20aSAndroid Build Coastguard Workerdef fix_guards(fpath, checkonly):
32*6dbdd20aSAndroid Build Coastguard Worker  with open(fpath, 'r', encoding='utf-8') as f:
33*6dbdd20aSAndroid Build Coastguard Worker    lines = [l.strip('\n') for l in f.readlines()]
34*6dbdd20aSAndroid Build Coastguard Worker
35*6dbdd20aSAndroid Build Coastguard Worker  if any(x.startswith('// fix_include_guards: off') for x in lines):
36*6dbdd20aSAndroid Build Coastguard Worker    return 0
37*6dbdd20aSAndroid Build Coastguard Worker
38*6dbdd20aSAndroid Build Coastguard Worker  res = []
39*6dbdd20aSAndroid Build Coastguard Worker  guard = re.sub(r'[^a-zA-Z0-9_-]', '_', fpath.upper()) + '_'
40*6dbdd20aSAndroid Build Coastguard Worker  replacements = 0
41*6dbdd20aSAndroid Build Coastguard Worker
42*6dbdd20aSAndroid Build Coastguard Worker  endif_line_idx = -1
43*6dbdd20aSAndroid Build Coastguard Worker  for line_idx in xrange(len(lines) - 1, -1, -1):
44*6dbdd20aSAndroid Build Coastguard Worker    if lines[line_idx].startswith('#endif'):
45*6dbdd20aSAndroid Build Coastguard Worker      endif_line_idx = line_idx
46*6dbdd20aSAndroid Build Coastguard Worker      break
47*6dbdd20aSAndroid Build Coastguard Worker  assert endif_line_idx > 0, fpath
48*6dbdd20aSAndroid Build Coastguard Worker
49*6dbdd20aSAndroid Build Coastguard Worker  line_idx = 0
50*6dbdd20aSAndroid Build Coastguard Worker  for line in lines:
51*6dbdd20aSAndroid Build Coastguard Worker    if replacements == 0 and line.startswith('#ifndef '):
52*6dbdd20aSAndroid Build Coastguard Worker      line = '#ifndef ' + guard
53*6dbdd20aSAndroid Build Coastguard Worker      replacements = 1
54*6dbdd20aSAndroid Build Coastguard Worker    elif replacements == 1 and line.startswith('#define '):
55*6dbdd20aSAndroid Build Coastguard Worker      line = '#define ' + guard
56*6dbdd20aSAndroid Build Coastguard Worker      replacements = 2
57*6dbdd20aSAndroid Build Coastguard Worker    elif line_idx == endif_line_idx and replacements == 2:
58*6dbdd20aSAndroid Build Coastguard Worker      assert (line.startswith('#endif'))
59*6dbdd20aSAndroid Build Coastguard Worker      line = '#endif  // ' + guard
60*6dbdd20aSAndroid Build Coastguard Worker    res.append(line)
61*6dbdd20aSAndroid Build Coastguard Worker    line_idx += 1
62*6dbdd20aSAndroid Build Coastguard Worker  if res == lines:
63*6dbdd20aSAndroid Build Coastguard Worker    return 0
64*6dbdd20aSAndroid Build Coastguard Worker  if checkonly:
65*6dbdd20aSAndroid Build Coastguard Worker    print('Wrong #include guards in %s' % fpath, file=sys.stderr)
66*6dbdd20aSAndroid Build Coastguard Worker    return 1
67*6dbdd20aSAndroid Build Coastguard Worker  with open(fpath, 'w', encoding='utf-8') as f:
68*6dbdd20aSAndroid Build Coastguard Worker    f.write('\n'.join(res) + '\n')
69*6dbdd20aSAndroid Build Coastguard Worker  return 1
70*6dbdd20aSAndroid Build Coastguard Worker
71*6dbdd20aSAndroid Build Coastguard Worker
72*6dbdd20aSAndroid Build Coastguard Workerdef main():
73*6dbdd20aSAndroid Build Coastguard Worker  checkonly = '--check-only' in sys.argv
74*6dbdd20aSAndroid Build Coastguard Worker  num_files_changed = 0
75*6dbdd20aSAndroid Build Coastguard Worker  for topdir in ('src', 'include', 'src/profiling/memory/include', 'test',
76*6dbdd20aSAndroid Build Coastguard Worker                 'tools'):
77*6dbdd20aSAndroid Build Coastguard Worker    for root, dirs, files in os.walk(topdir):
78*6dbdd20aSAndroid Build Coastguard Worker      for name in files:
79*6dbdd20aSAndroid Build Coastguard Worker        if not name.endswith('.h'):
80*6dbdd20aSAndroid Build Coastguard Worker          continue
81*6dbdd20aSAndroid Build Coastguard Worker        fpath = os.path.join(root, name)
82*6dbdd20aSAndroid Build Coastguard Worker        if fpath in EXCLUDED_FILES:
83*6dbdd20aSAndroid Build Coastguard Worker          continue
84*6dbdd20aSAndroid Build Coastguard Worker        num_files_changed += fix_guards(fpath, checkonly)
85*6dbdd20aSAndroid Build Coastguard Worker  if checkonly:
86*6dbdd20aSAndroid Build Coastguard Worker    return 0 if num_files_changed == 0 else 1
87*6dbdd20aSAndroid Build Coastguard Worker  else:
88*6dbdd20aSAndroid Build Coastguard Worker    print('%d files changed' % num_files_changed)
89*6dbdd20aSAndroid Build Coastguard Worker
90*6dbdd20aSAndroid Build Coastguard Worker
91*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__':
92*6dbdd20aSAndroid Build Coastguard Worker  sys.exit(main())
93