Last active
August 19, 2021 00:49
-
-
Save marshallward/8215f7947e184712e729de5e1828004e to your computer and use it in GitHub Desktop.
trailer2.py
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 python | |
"""Subroutines for Validating the whitespace of the source code.""" | |
import argparse | |
import sys | |
import flint | |
def parse_command_line(): | |
"""Parse the command line positional and optional arguments. | |
This is the highest level procedure invoked from the very end of the | |
script. | |
""" | |
# Arguments | |
parser = argparse.ArgumentParser( | |
description='trailer.py checks Fortran files for trailing white ' | |
'space.', | |
epilog='Written by A.Adcroft, 2017.' | |
) | |
parser.add_argument( | |
'files_or_dirs', type=str, nargs='+', | |
metavar='FILE|DIR', | |
help='Fortran files or directory in which to search for Fortran files ' | |
'(with .f, .f90, .F90 suffixes).''' | |
) | |
parser.add_argument( | |
'-e', '--exclude_dir', type=str, action='append', | |
metavar='DIR', | |
help='''Exclude directories from search that end in DIR.''' | |
) | |
parser.add_argument( | |
'-l', '--line_length', type=int, default=512, | |
help='''Maximum allowed length of a line.''' | |
) | |
parser.add_argument( | |
'-s', '--source_line_length', type=int, default=132, | |
help='''Maximum allowed length of a source line excluding comments.''' | |
) | |
parser.add_argument( | |
'-d', '--debug', action='store_true', | |
help='turn on debugging information.' | |
) | |
args = parser.parse_args() | |
main(args) | |
def main(args): | |
"""Do the actual work.""" | |
if args.debug: | |
print(args) | |
proj = flint.parse(*args.files_or_dirs, excludes=args.exclude_dir) | |
if args.debug: | |
print('Found: ', [src.path for src in proj.sources]) | |
# For each file, check for trailing white space | |
fail = False | |
for src in proj.sources: | |
this = scan_file(src, line_length=args.line_length, | |
source_line_length=args.source_line_length) | |
fail = fail or this | |
if fail: | |
sys.exit(1) | |
def scan_file(source, line_length=512, source_line_length=132): | |
"""Scan file for trailing white space.""" | |
def msg(filename, lineno, mesg, line=None): | |
log = '{}, line {}: {}'.format(filename, lineno, mesg) | |
if line is not None: | |
log += ' "{}"'.format(''.join(line)) | |
print(log) | |
white_space_detected = False | |
tabs_space_detected = False | |
long_line_detected = False | |
lineno = 0 | |
for line in source.lines: | |
lineno += 1 | |
# Report trailing whitespace | |
if line and line[-1] and line[-1][-1].isspace(): | |
white_space_detected = True | |
if all(tok.isspace() for tok in line): | |
msg(source.path, lineno, 'Blank line contains spaces') | |
else: | |
msg(source.path, lineno, 'Trailing space detected', line) | |
# Report any tab stop characters | |
# NOTE: This also reports tab stops in comments and strings. | |
if any('\t' in tok for tok in line): | |
tab_space_detected = True | |
if all(tok.isspace() for tok in line): | |
msg(source.path, lineno, 'Blank line contains tabs') | |
else: | |
msg(source.path, lineno, 'Tab detected', line) | |
# Report excessive line length | |
if sum(len(tok) for tok in line) > line_length: | |
long_line_detected = True | |
if all(tok.isspace() for tok in line): | |
msg(source.path, lineno, | |
'Blank line exceeds line length limit') | |
else: | |
msg(source.path, lineno, 'Line length exceeded', line) | |
# Report excessive source line length | |
# NOTE: Source line test includes whitespace preceding comments | |
srclen = sum(len(tok) for tok in line if not tok.startswith('!')) | |
if srclen > source_line_length: | |
msg(source.path, lineno, 'Non-comment line length exceeded', line) | |
return white_space_detected or tabs_space_detected or long_line_detected | |
# Invoke parse_command_line(), the top-level procedure | |
if __name__ == '__main__': | |
parse_command_line() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment