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