Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python
      2 # Copyright (C) 2017 The Android Open Source Project
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #      http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 
     16 import os
     17 import re
     18 import sys
     19 
     20 def fix_guards(fpath, checkonly):
     21   with open(fpath, 'rb') as f:
     22     lines = [l.strip('\n') for l in f.readlines()]
     23   res = []
     24   guard = re.sub(r'[^a-zA-Z0-9_-]', '_', fpath.upper()) + '_'
     25   replacements = 0
     26 
     27   endif_line_idx = -1
     28   for line_idx in xrange(len(lines) - 1, -1, -1):
     29     if lines[line_idx].startswith('#endif'):
     30       endif_line_idx = line_idx
     31       break
     32   assert endif_line_idx > 0, fpath
     33 
     34   line_idx = 0
     35   for line in lines:
     36     if replacements == 0 and line.startswith('#ifndef '):
     37       line = '#ifndef ' + guard
     38       replacements = 1
     39     elif replacements == 1 and line.startswith('#define '):
     40       line = '#define ' + guard
     41       replacements = 2
     42     elif line_idx == endif_line_idx and replacements == 2:
     43       assert(line.startswith('#endif'))
     44       line = '#endif  // ' + guard
     45     res.append(line)
     46     line_idx += 1
     47   if res == lines:
     48     return 0
     49   if checkonly:
     50     print >>sys.stderr, 'Wrong #include guards in %s' % fpath
     51     return 1
     52   with open(fpath, 'w') as f:
     53     f.write('\n'.join(res) + '\n')
     54   return 1
     55 
     56 def main():
     57   checkonly = '--check-only' in sys.argv
     58   num_files_changed = 0
     59   for topdir in ('src', 'include', 'test', 'tools'):
     60     for root, dirs, files in os.walk(topdir):
     61       for name in files:
     62         if not name.endswith('.h'):
     63           continue
     64         fpath = os.path.join(root, name)
     65         num_files_changed += fix_guards(fpath, checkonly)
     66   if checkonly:
     67     return 0 if num_files_changed == 0 else 1
     68   else:
     69     print '%d files changed' % num_files_changed
     70 
     71 if __name__ == '__main__':
     72   sys.exit(main())
     73