xref: /aosp_15_r20/external/skia/tools/sanitize_source_files.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker#!/usr/bin/env python
2*c8dee2aaSAndroid Build Coastguard Worker# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3*c8dee2aaSAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*c8dee2aaSAndroid Build Coastguard Worker# found in the LICENSE file.
5*c8dee2aaSAndroid Build Coastguard Worker
6*c8dee2aaSAndroid Build Coastguard Worker
7*c8dee2aaSAndroid Build Coastguard Worker"""Module that sanitizes source files with specified modifiers."""
8*c8dee2aaSAndroid Build Coastguard Worker
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Workerfrom __future__ import print_function
11*c8dee2aaSAndroid Build Coastguard Workerimport commands
12*c8dee2aaSAndroid Build Coastguard Workerimport os
13*c8dee2aaSAndroid Build Coastguard Workerimport sys
14*c8dee2aaSAndroid Build Coastguard Worker
15*c8dee2aaSAndroid Build Coastguard Worker
16*c8dee2aaSAndroid Build Coastguard Worker_FILE_EXTENSIONS_TO_SANITIZE = ['cpp', 'h', 'c']
17*c8dee2aaSAndroid Build Coastguard Worker
18*c8dee2aaSAndroid Build Coastguard Worker_SUBDIRS_TO_IGNORE = ['.git', '.svn', 'third_party']
19*c8dee2aaSAndroid Build Coastguard Worker
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Workerdef SanitizeFilesWithModifiers(directory, file_modifiers, line_modifiers):
22*c8dee2aaSAndroid Build Coastguard Worker  """Sanitizes source files with the specified file and line modifiers.
23*c8dee2aaSAndroid Build Coastguard Worker
24*c8dee2aaSAndroid Build Coastguard Worker  Args:
25*c8dee2aaSAndroid Build Coastguard Worker    directory: string - The directory which will be recursively traversed to
26*c8dee2aaSAndroid Build Coastguard Worker        find source files to apply modifiers to.
27*c8dee2aaSAndroid Build Coastguard Worker    file_modifiers: list - file-modification methods which should be applied to
28*c8dee2aaSAndroid Build Coastguard Worker        the complete file content (Eg: EOFOneAndOnlyOneNewlineAdder).
29*c8dee2aaSAndroid Build Coastguard Worker    line_modifiers: list - line-modification methods which should be applied to
30*c8dee2aaSAndroid Build Coastguard Worker        lines in a file (Eg: TabReplacer).
31*c8dee2aaSAndroid Build Coastguard Worker  """
32*c8dee2aaSAndroid Build Coastguard Worker  for item in os.listdir(directory):
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker    full_item_path = os.path.join(directory, item)
35*c8dee2aaSAndroid Build Coastguard Worker
36*c8dee2aaSAndroid Build Coastguard Worker    if os.path.isfile(full_item_path):  # Item is a file.
37*c8dee2aaSAndroid Build Coastguard Worker
38*c8dee2aaSAndroid Build Coastguard Worker      # Only sanitize files with extensions we care about.
39*c8dee2aaSAndroid Build Coastguard Worker      if (len(full_item_path.split('.')) > 1 and
40*c8dee2aaSAndroid Build Coastguard Worker          full_item_path.split('.')[-1] in _FILE_EXTENSIONS_TO_SANITIZE):
41*c8dee2aaSAndroid Build Coastguard Worker        f = file(full_item_path)
42*c8dee2aaSAndroid Build Coastguard Worker        try:
43*c8dee2aaSAndroid Build Coastguard Worker          lines = f.readlines()
44*c8dee2aaSAndroid Build Coastguard Worker        finally:
45*c8dee2aaSAndroid Build Coastguard Worker          f.close()
46*c8dee2aaSAndroid Build Coastguard Worker
47*c8dee2aaSAndroid Build Coastguard Worker        new_lines = []  # Collect changed lines here.
48*c8dee2aaSAndroid Build Coastguard Worker        line_number = 0  # Keeps track of line numbers in the source file.
49*c8dee2aaSAndroid Build Coastguard Worker        write_to_file = False  # File is written to only if this flag is set.
50*c8dee2aaSAndroid Build Coastguard Worker
51*c8dee2aaSAndroid Build Coastguard Worker        # Run the line modifiers for each line in this file.
52*c8dee2aaSAndroid Build Coastguard Worker        for line in lines:
53*c8dee2aaSAndroid Build Coastguard Worker          original_line = line
54*c8dee2aaSAndroid Build Coastguard Worker          line_number += 1
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker          for modifier in line_modifiers:
57*c8dee2aaSAndroid Build Coastguard Worker            line = modifier(line, full_item_path, line_number)
58*c8dee2aaSAndroid Build Coastguard Worker            if original_line != line:
59*c8dee2aaSAndroid Build Coastguard Worker              write_to_file = True
60*c8dee2aaSAndroid Build Coastguard Worker          new_lines.append(line)
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker        # Run the file modifiers.
63*c8dee2aaSAndroid Build Coastguard Worker        old_content = ''.join(lines)
64*c8dee2aaSAndroid Build Coastguard Worker        new_content = ''.join(new_lines)
65*c8dee2aaSAndroid Build Coastguard Worker        for modifier in file_modifiers:
66*c8dee2aaSAndroid Build Coastguard Worker          new_content = modifier(new_content, full_item_path)
67*c8dee2aaSAndroid Build Coastguard Worker        if new_content != old_content:
68*c8dee2aaSAndroid Build Coastguard Worker          write_to_file = True
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker        # Write modifications to the file.
71*c8dee2aaSAndroid Build Coastguard Worker        if write_to_file:
72*c8dee2aaSAndroid Build Coastguard Worker          f = file(full_item_path, 'w')
73*c8dee2aaSAndroid Build Coastguard Worker          try:
74*c8dee2aaSAndroid Build Coastguard Worker            f.write(new_content)
75*c8dee2aaSAndroid Build Coastguard Worker          finally:
76*c8dee2aaSAndroid Build Coastguard Worker            f.close()
77*c8dee2aaSAndroid Build Coastguard Worker          print('Made changes to %s' % full_item_path)
78*c8dee2aaSAndroid Build Coastguard Worker
79*c8dee2aaSAndroid Build Coastguard Worker    elif item not in _SUBDIRS_TO_IGNORE:
80*c8dee2aaSAndroid Build Coastguard Worker      # Item is a directory recursively call the method.
81*c8dee2aaSAndroid Build Coastguard Worker      SanitizeFilesWithModifiers(full_item_path, file_modifiers, line_modifiers)
82*c8dee2aaSAndroid Build Coastguard Worker
83*c8dee2aaSAndroid Build Coastguard Worker
84*c8dee2aaSAndroid Build Coastguard Worker############## Line Modification methods ##############
85*c8dee2aaSAndroid Build Coastguard Worker
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Workerdef TrailingWhitespaceRemover(line, file_path, line_number):
88*c8dee2aaSAndroid Build Coastguard Worker  """Strips out trailing whitespaces from the specified line."""
89*c8dee2aaSAndroid Build Coastguard Worker  stripped_line = line.rstrip() + '\n'
90*c8dee2aaSAndroid Build Coastguard Worker  if line != stripped_line:
91*c8dee2aaSAndroid Build Coastguard Worker    print('Removing trailing whitespace in %s:%s' % (file_path, line_number))
92*c8dee2aaSAndroid Build Coastguard Worker  return stripped_line
93*c8dee2aaSAndroid Build Coastguard Worker
94*c8dee2aaSAndroid Build Coastguard Worker
95*c8dee2aaSAndroid Build Coastguard Workerdef CrlfReplacer(line, file_path, line_number):
96*c8dee2aaSAndroid Build Coastguard Worker  """Replaces CRLF with LF."""
97*c8dee2aaSAndroid Build Coastguard Worker  if '\r\n' in line:
98*c8dee2aaSAndroid Build Coastguard Worker    print('Replacing CRLF with LF in %s:%s' % (file_path, line_number))
99*c8dee2aaSAndroid Build Coastguard Worker  return line.replace('\r\n', '\n')
100*c8dee2aaSAndroid Build Coastguard Worker
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Workerdef TabReplacer(line, file_path, line_number):
103*c8dee2aaSAndroid Build Coastguard Worker  """Replaces Tabs with 4 whitespaces."""
104*c8dee2aaSAndroid Build Coastguard Worker  if '\t' in line:
105*c8dee2aaSAndroid Build Coastguard Worker    print('Replacing Tab with whitespace in %s:%s' % (file_path, line_number))
106*c8dee2aaSAndroid Build Coastguard Worker  return line.replace('\t', '    ')
107*c8dee2aaSAndroid Build Coastguard Worker
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Worker############## File Modification methods ##############
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker
112*c8dee2aaSAndroid Build Coastguard Workerdef CopywriteChecker(file_content, unused_file_path):
113*c8dee2aaSAndroid Build Coastguard Worker  """Ensures that the copywrite information is correct."""
114*c8dee2aaSAndroid Build Coastguard Worker  # TODO(rmistry): Figure out the legal implications of changing old copyright
115*c8dee2aaSAndroid Build Coastguard Worker  # headers.
116*c8dee2aaSAndroid Build Coastguard Worker  return file_content
117*c8dee2aaSAndroid Build Coastguard Worker
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Workerdef EOFOneAndOnlyOneNewlineAdder(file_content, file_path):
120*c8dee2aaSAndroid Build Coastguard Worker  """Adds one and only one LF at the end of the file."""
121*c8dee2aaSAndroid Build Coastguard Worker  if file_content and (file_content[-1] != '\n' or file_content[-2:-1] == '\n'):
122*c8dee2aaSAndroid Build Coastguard Worker    file_content = file_content.rstrip()
123*c8dee2aaSAndroid Build Coastguard Worker    file_content += '\n'
124*c8dee2aaSAndroid Build Coastguard Worker    print('Added exactly one newline to %s' % file_path)
125*c8dee2aaSAndroid Build Coastguard Worker  return file_content
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker
128*c8dee2aaSAndroid Build Coastguard Workerdef SvnEOLChecker(file_content, file_path):
129*c8dee2aaSAndroid Build Coastguard Worker  """Sets svn:eol-style property to LF."""
130*c8dee2aaSAndroid Build Coastguard Worker  output = commands.getoutput(
131*c8dee2aaSAndroid Build Coastguard Worker      'svn propget svn:eol-style %s' % file_path)
132*c8dee2aaSAndroid Build Coastguard Worker  if output != 'LF':
133*c8dee2aaSAndroid Build Coastguard Worker    print('Setting svn:eol-style property to LF in %s' % file_path)
134*c8dee2aaSAndroid Build Coastguard Worker    os.system('svn ps svn:eol-style LF %s' % file_path)
135*c8dee2aaSAndroid Build Coastguard Worker  return file_content
136*c8dee2aaSAndroid Build Coastguard Worker
137*c8dee2aaSAndroid Build Coastguard Worker
138*c8dee2aaSAndroid Build Coastguard Worker#######################################################
139*c8dee2aaSAndroid Build Coastguard Worker
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Workerif '__main__' == __name__:
142*c8dee2aaSAndroid Build Coastguard Worker  sys.exit(SanitizeFilesWithModifiers(
143*c8dee2aaSAndroid Build Coastguard Worker      os.getcwd(),
144*c8dee2aaSAndroid Build Coastguard Worker      file_modifiers=[
145*c8dee2aaSAndroid Build Coastguard Worker          CopywriteChecker,
146*c8dee2aaSAndroid Build Coastguard Worker          EOFOneAndOnlyOneNewlineAdder,
147*c8dee2aaSAndroid Build Coastguard Worker          SvnEOLChecker,
148*c8dee2aaSAndroid Build Coastguard Worker      ],
149*c8dee2aaSAndroid Build Coastguard Worker      line_modifiers=[
150*c8dee2aaSAndroid Build Coastguard Worker          CrlfReplacer,
151*c8dee2aaSAndroid Build Coastguard Worker          TabReplacer,
152*c8dee2aaSAndroid Build Coastguard Worker          TrailingWhitespaceRemover,
153*c8dee2aaSAndroid Build Coastguard Worker      ],
154*c8dee2aaSAndroid Build Coastguard Worker  ))
155