Created
November 5, 2016 12:06
-
-
Save vampy/07cbaccb1cd6a138c128005025be7156 to your computer and use it in GitHub Desktop.
Remove whitespaces/tabs from different files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# | |
# 2014, By konstin (http://github/konstin) | |
# 2015, Modified by leyyin | |
# | |
# Removes all trailing whitespaces and replaces all tabs with four spaces, the | |
# files with a given extension in a recursively searched directory. | |
# It can also count the number of code lines excluding comments and blank | |
# lines. | |
# | |
# Tested with python 2.7 and python 3 | |
import os | |
import argparse | |
import sys | |
def main(directory, is_statistics, is_dry_run, extensions, comments_start): | |
lines_total = 0 | |
lines_comments = 0 | |
file_counter = 0 | |
files_affected = 0 | |
for dir_path, _, file_names in os.walk(directory): | |
if is_statistics: | |
file_counter += len(file_names) | |
for file_name in file_names: | |
_, file_extension = os.path.splitext(file_name) | |
# File does not have an extension | |
if not file_extension: | |
continue | |
# Not a valid extension. Note: extensions have in the 0 position a dot, eg: '.hpp', '.cpp' | |
if file_extension[1:] not in extensions: | |
continue | |
if is_statistics: | |
files_affected += 1 | |
# Read whole file | |
path_file = os.path.join(dir_path, file_name) | |
with open(path_file, 'r') as f: | |
lines = f.readlines() | |
if is_statistics: | |
lines_total += len(lines) | |
# Scan lines | |
is_modified = False | |
for i, line in enumerate(lines): | |
original_line = line | |
# Replace tabs with four spaces | |
line = line.replace('\t', ' ') | |
line_rstrip = line.rstrip() | |
if line_rstrip: # Don't de-indent empty lines | |
line = line_rstrip + '\n' | |
# Count the number of comments | |
if is_statistics: | |
line_lstrip = line.lstrip() | |
if any([line_lstrip.startswith(c) for c in comments_start]): | |
lines_comments += 1 | |
# Indicate that we want to write to the current file | |
if original_line != line: | |
lines[i] = line # Replace original line | |
if not is_modified: | |
is_modified = True | |
# Write back modified lines | |
if not is_dry_run and is_modified: | |
with open(path_file, 'w') as f: | |
f.writelines(lines) | |
if is_statistics: | |
print('Total number of files in {0}: {1}'.format(directory, file_counter)) | |
print('Total number of files affected in {0}: {1}'.format(directory, files_affected)) | |
print('Lines in total: {0}'.format(lines_total)) | |
print(' empty/comments: {0}'.format(lines_comments)) | |
print('↳ excluding comments and blank lines: {0}'.format(lines_total - lines_comments), end='\n' * 2) | |
print('Finished.') | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description='Remove whitespace from C/C++ files.') | |
parser.add_argument('directory', default='../src', nargs='?', | |
help='the directory where all the source files are located. (default: %(default)s)') | |
parser.add_argument('--dry-run', dest='dry_run', action='store_true', | |
help='do a dry run. Do not modify/write any files. (default: %(default)s)') | |
parser.add_argument('--statistics', dest='statistics', action='store_true', | |
help='display statistics (count files and lines if enabled). On by default.') | |
parser.add_argument('--no-statistics', dest='statistics', action='store_false', help='do not display statistics.') | |
parser.add_argument('--extensions', default=["cpp", "hpp", "c", "h"], nargs='+', | |
help='set file extensions. Eg: --extensions cpp hpp (default: %(default)s).') | |
parser.add_argument('--comments-start', default=['//', '/*', '*'], nargs='+', | |
help='set how line comments start. Eg: --comments-start // \'*\'. (default: %(default)s).') | |
parser.set_defaults(statistics=True) | |
parser.set_defaults(dry_run=False) | |
args = parser.parse_args() | |
if not os.path.exists(args.directory): | |
print('ERROR: The directory {0} does not exist'.format(args.directory)) | |
sys.exit(1) | |
print(args) | |
main(args.directory, args.statistics, args.dry_run, args.extensions, args.comments_start) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment