Prettify: more flexible command line interface

Can now be installed as 'fprettify' and can be more easily invoked from command line
and can be integrated into editors.
- Fixes in reformatter for better editor support
- errors / warnings to stderr and can use stdin / stdout
- remove unnecessary checks
- warnings can be deactivated
- backup is optional
- prettify has its own directory


svn-origin-rev: 17300
This commit is contained in:
Patrick Seewald 2016-08-26 07:38:50 +00:00
parent 4acc5dfc39
commit 8a4bb01b58
8 changed files with 195 additions and 129 deletions

View file

@ -181,7 +181,7 @@ test:
testbg:
@echo "testing: $(ONEVERSION) : full log in $(TSTDIR)/regtest.log "
@$(TOOLSRC)/regtesting/do_regtest -nobuild -nosvn -arch $(ARCH) -version $(ONEVERSION) -cp2kdir ../../../ $(TESTOPTS) >& $(TSTDIR)/regtest.log
@$(TOOLSRC)/regtesting/do_regtest -nobuild -nosvn -arch $(ARCH) -version $(ONEVERSION) -cp2kdir ../../../ $(TESTOPTS) >& $(TSTDIR)/regtest.log
@cat `grep 'regtesting location error_summary file:' $(TSTDIR)/regtest.log | awk '{print $$NF}'`
@cat `grep 'regtesting location summary file:' $(TSTDIR)/regtest.log | awk '{print $$NF}'`
@grep "Number of FAILED tests 0" $(TSTDIR)/regtest.log >& /dev/null
@ -229,8 +229,8 @@ OTHER_HELP += "install : Print installation help"
clean:
rm -rf $(LIBCUSMM_DIR)/libcusmm.cu $(LIBCUSMM_DIR)/libcusmm_part*.cu
rm -rf $(foreach v, $(VERSION), $(MAINOBJDIR)/$(ARCH)/$(v)/*.o)
rm -rf $(foreach v, $(VERSION), $(MAINOBJDIR)/$(ARCH)/$(v)/*.mod $(MAINOBJDIR)/$(ARCH)/$(v)/*.MOD $(MAINOBJDIR)/$(ARCH)/$(v)/*.smod)
rm -rf $(foreach v, $(VERSION), $(MAINOBJDIR)/$(ARCH)/$(v)/*.dep)
rm -rf $(foreach v, $(VERSION), $(MAINOBJDIR)/$(ARCH)/$(v)/*.mod $(MAINOBJDIR)/$(ARCH)/$(v)/*.MOD $(MAINOBJDIR)/$(ARCH)/$(v)/*.smod)
rm -rf $(foreach v, $(VERSION), $(MAINOBJDIR)/$(ARCH)/$(v)/*.dep)
OTHER_HELP += "clean : Remove intermediate object and mod files, but not the libraries and executables, for given ARCH and VERSION"
execlean:
@ -300,7 +300,7 @@ TOOL_HELP += "prettyclean : Remove prettify marker files and preprettify directo
$(PRETTYOBJDIR)/%.pretty: %.F $(DOXIFYOBJDIR)/%.doxified
@mkdir -p $(PRETTYOBJDIR)
cd $(dir $<); $(TOOLSRC)/prettify.py --backup-dir=$(PRETTYOBJDIR) $(notdir $<)
cd $(dir $<); $(TOOLSRC)/prettify/fprettify.py --do-backup --backup-dir=$(PRETTYOBJDIR) $(notdir $<)
@touch $@
$(PRETTYOBJDIR)/%.pretty: %.c $(DOXIFYOBJDIR)/%.doxified
@ -427,7 +427,7 @@ CPPSHELL := -D__COMPILE_ARCH="\"$(ARCH)\""\
endif
ifneq ($(CPP),)
# always add the SRCDIR to the include path (-I here might not be portable)
# always add the SRCDIR to the include path (-I here might not be portable)
CPPFLAGS += $(CPPSHELL) -I$(SRCDIR)
else
FCFLAGS += $(CPPSHELL)

View file

@ -58,7 +58,6 @@ class CharFilter(object):
return (pos, char)
def next(self):
""" python 2 version"""
pos, char = self._it.next()
@ -77,6 +76,7 @@ class CharFilter(object):
return (pos, char)
class InputStream(object):
"""
Class to read logical Fortran lines from a Fortran file.
@ -217,8 +217,10 @@ def parseRoutine(inFile):
subF.close()
except:
import traceback
print("error trying to follow include ", m.group('file'))
print("warning this might lead to the removal of used variables")
sys.stderr.write(
"error trying to follow include " + m.group('file') + '\n')
sys.stderr.write(
"warning this might lead to the removal of used variables\n")
traceback.print_exc()
if jline:
routine['begin'] = lines
@ -357,8 +359,10 @@ def parseRoutine(inFile):
subF.close()
except:
import traceback
print("error trying to follow include ", m.group('file'))
print("warning this might lead to the removal of used variables")
sys.stderr.write(
"error trying to follow include " + m.group('file') + '\n')
sys.stderr.write(
"warning this might lead to the removal of used variables\n")
traceback.print_exc()
(jline, _, lines) = stream.nextFortranLine()
return routine
@ -596,7 +600,7 @@ def writeDeclarations(parsedDeclarations, file):
writeExtendedDeclaration(d, file)
def cleanDeclarations(routine, logFile=sys.stdout):
def cleanDeclarations(routine, logFile=sys.stderr):
"""cleans up the declaration part of the given parsed routine
removes unused variables"""
global rVar
@ -708,8 +712,8 @@ def cleanDeclarations(routine, logFile=sys.stdout):
if argDeclDict.has_key(arg):
argDecl.append(argDeclDict[arg])
else:
print("warning, implicitly typed argument '",
arg, "' in routine", routine['name'])
sys.stderr.write("warning, implicitly typed argument '" +
arg + "' in routine " + routine['name'] + '\n')
if routine['kind'].lower() == 'function':
aDecl = argDecl[:-1]
else:
@ -868,8 +872,6 @@ def parseUse(inFile):
# parse use
m = useParseRe.match(jline)
if m:
if comments:
print("jline", jline, "lines", lines)
useAtt = {'module': m.group('module'), 'comments': []}
if m.group('only'):
@ -1001,7 +1003,7 @@ def prepareImplicitUses(modules):
return mods
def cleanUse(modulesDict, rest, implicitUses=None, logFile=sys.stdout):
def cleanUse(modulesDict, rest, implicitUses=None, logFile=sys.stderr):
"""Removes the unneded modules (the ones that are not used in rest)"""
global rUse
exceptions = {}
@ -1048,12 +1050,12 @@ def resetModuleN(moduleName, lines):
flags=re.IGNORECASE)
for i in range(len(lines)):
lines[i] = moduleNRe.sub(
" "*indentSize + "CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = '" +
" " * indentSize + "CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = '" +
moduleName + "'",
lines[i])
def rewriteFortranFile(inFile, outFile, indent, decl_linelength, decl_offset, logFile=sys.stdout, orig_filename=None):
def rewriteFortranFile(inFile, outFile, indent, decl_linelength, decl_offset, logFile=sys.stderr, orig_filename=None):
"""rewrites the use statements and declarations of inFile to outFile.
It sorts them and removes the repetitions."""
import os.path
@ -1080,9 +1082,6 @@ def rewriteFortranFile(inFile, outFile, indent, decl_linelength, decl_offset, lo
if not orig_filename:
orig_filename = inFile.name
fn = os.path.basename(orig_filename).rsplit(".", 1)[0]
if (m.group('moduleName') != fn):
raise SyntaxError("Module name is different from filename (" +
m.group('moduleName') + "!=" + fn + ")")
break
try:
modulesDict = parseUse(inFile)
@ -1104,7 +1103,7 @@ def rewriteFortranFile(inFile, outFile, indent, decl_linelength, decl_offset, lo
nonStPrep = 0
for line in modulesDict['origLines']:
if (re.search('^#', line) and not commonUsesRe.match(line)):
print('noMatch', repr(line))
sys.stderr.write('noMatch ' + repr(line) + '\n')
nonStPrep = 1
if nonStPrep:
logFile.write(
@ -1124,8 +1123,8 @@ def rewriteFortranFile(inFile, outFile, indent, decl_linelength, decl_offset, lo
implicitUses = prepareImplicitUses(
implicitUsesRaw['modules'])
except:
print ("ERROR trying to parse use statements contained in common",
"uses precompiler file ", inc_absfn)
sys.stderr.write(
"ERROR trying to parse use statements contained in common uses precompiler file " + inc_absfn + '\n')
raise
cleanUse(modulesDict, rest,
implicitUses=implicitUses, logFile=logFile)

View file

@ -38,6 +38,7 @@
import re
import sys
import os
from formatting.normalizeFortranFile import useParseRe, typeRe, InputStream, CharFilter, ompRe, ompDirRe
#=========================================================================
@ -45,7 +46,7 @@ from formatting.normalizeFortranFile import useParseRe, typeRe, InputStream, Cha
RE_FLAGS = re.IGNORECASE # all regex should be case insensitive
FORTRAN_DEFAULT_ERROR_MESSAGE = " Syntax error - this script can not handle invalid Fortran files."
FORTRAN_DEFAULT_ERROR_MESSAGE = " Syntax error - this formatter can not handle invalid Fortran files."
FORMATTER_ERROR_MESSAGE = " Wrong usage of formatting-specific directives '&', '!&', '!&<' or '!&>'."
EOL_STR = r"\s*;?\s*$" # end of fortran line
@ -91,7 +92,8 @@ PROG_RE = re.compile(SOL_STR + r"PROGRAM\s+\w+" + EOL_STR, RE_FLAGS)
ENDPROG_RE = re.compile(
SOL_STR + r"END\s*PROGRAM(\s+\w+)?" + EOL_STR, RE_FLAGS)
INTERFACE_RE = re.compile(r"^([^\"'!]* )?INTERFACE(\s+\w+)?" + EOL_STR, RE_FLAGS)
INTERFACE_RE = re.compile(
r"^([^\"'!]* )?INTERFACE(\s+\w+)?" + EOL_STR, RE_FLAGS)
ENDINTERFACE_RE = re.compile(
SOL_STR + r"END\s*INTERFACE(\s+\w+)?" + EOL_STR, RE_FLAGS)
@ -178,7 +180,7 @@ class F90Indenter(object):
valid_new = True
scopes.append(what_new)
if debug:
print(f_line)
sys.stderr.write(f_line + '\n')
break
# check statements that continue scope
@ -193,7 +195,7 @@ class F90Indenter(object):
if what == what_con:
valid_con = True
if debug:
print(f_line)
sys.stderr.write(f_line + '\n')
break
# check statements that end scope
@ -208,7 +210,7 @@ class F90Indenter(object):
if what == what_end:
valid_end = True
if debug:
print(f_line)
sys.stderr.write(f_line + '\n')
break
# deal with line breaks
@ -302,7 +304,7 @@ class F90Aligner(object):
if pos + 1 < len(lines):
self._line_indents.append(self._br_indent_list[-1])
if len(self._br_indent_list) > 2 or self._level:
if (len(self._br_indent_list) > 2 or self._level):
raise SyntaxError(self._filename + ':' + str(self._line_nr) +
':' + FORTRAN_DEFAULT_ERROR_MESSAGE)
@ -416,12 +418,15 @@ def inspect_ffile_format(infile, indent_size):
indents = []
stream = InputStream(infile)
prev_offset = 0
first_indent = -1
while 1:
f_line, _, lines = stream.nextFortranLine()
if not lines:
break
offset = len(lines[0]) - len(lines[0].lstrip(' '))
if f_line.strip() and first_indent == -1:
first_indent = offset
indents.append(offset - prev_offset)
if not adopt: # do not adopt indentations but impose fixed rel. ind.
# but don't impose indentation for blocked do/if constructs
@ -432,7 +437,7 @@ def inspect_ffile_format(infile, indent_size):
# can not handle f77 style constructs
if F77_STYLE.search(f_line):
is_f90 = False
return indents, is_f90
return indents, first_indent, is_f90
#=========================================================================
@ -441,11 +446,11 @@ def format_single_fline(f_line, whitespace, linebreak_pos, ampersand_sep, filena
"""
format a single Fortran line - imposes white space formatting
and inserts linebreaks.
Takes a logical Fortran line `f_line` as input as well as the positions
of the linebreaks (`linebreak_pos`), and the number of separating whitespace
characters before ampersand (`ampersand_sep`).
Takes a logical Fortran line `f_line` as input as well as the positions
of the linebreaks (`linebreak_pos`), and the number of separating whitespace
characters before ampersand (`ampersand_sep`).
`filename` and `line_nr` just for error messages.
The higher `whitespace`, the more white space characters inserted -
The higher `whitespace`, the more white space characters inserted -
whitespace = 0, 1, 2 are currently supported.
auto formatting can be turned off by setting `auto_format` to False.
"""
@ -664,7 +669,7 @@ def format_single_fline(f_line, whitespace, linebreak_pos, ampersand_sep, filena
#=========================================================================
def reformat_ffile(infile, outfile, logFile=sys.stdout, indent_size=2, whitespace=2, orig_filename=None):
def reformat_ffile(infile, outfile, logFile=sys.stderr, indent_size=2, whitespace=2, orig_filename=None):
"""
main method to be invoked for formatting a Fortran file.
"""
@ -678,7 +683,8 @@ def reformat_ffile(infile, outfile, logFile=sys.stdout, indent_size=2, whitespac
indenter = F90Indenter(orig_filename)
req_indents, is_f90 = inspect_ffile_format(infile, indent_size)
req_indents, first_indent, is_f90 = inspect_ffile_format(
infile, indent_size)
infile.seek(0)
if not is_f90:
@ -690,6 +696,7 @@ def reformat_ffile(infile, outfile, logFile=sys.stdout, indent_size=2, whitespac
nfl = 0 # fortran line counter
do_indent = True
use_same_line = False
stream = InputStream(infile)
skip_blank = False
in_manual_block = False
@ -744,23 +751,27 @@ def reformat_ffile(infile, outfile, logFile=sys.stdout, indent_size=2, whitespac
is_empty = EMPTY_RE.search(f_line) # blank line or comment only line
if useParseRe.match(f_line):
pass # do not touch use statements cleaned up by existing prettify
do_indent = False
elif ompDirRe.match(f_line):
# move '!$OMP' to line start, otherwise don't format omp directives
lines = ['!$OMP' + (len(l) - len(l.lstrip())) *
' ' + ompDirRe.sub('', l, count=1) for l in lines]
pass
do_indent = False
elif lines[0].startswith('#'): # preprocessor macros
assert len(lines) == 1
do_indent = False
elif EMPTY_RE.search(f_line): # empty lines including comment lines
assert len(lines) == 1
if any(comments):
if lines[0].startswith('!'):
pass # don't indent unindented comment lines
# don't indent unindented comments
do_indent = False
else:
indent[0] = indenter.get_fline_indent()
elif skip_blank:
continue
else:
do_indent = False
lines = [l.strip(' ') for l in lines]
else:
@ -850,9 +861,12 @@ def reformat_ffile(infile, outfile, logFile=sys.stdout, indent_size=2, whitespac
line_length += 1
if do_indent:
ind_use = ind
ind_use = ind + first_indent
else:
ind_use = 1
if use_same_line:
ind_use = 1
else:
ind_use = 0
if ind_use + line_length <= 133: # 132 plus 1 newline char
outfile.write('!$' * is_omp_conditional + ' ' *
(ind_use - 2 * is_omp_conditional +
@ -869,12 +883,15 @@ def reformat_ffile(infile, outfile, logFile=sys.stdout, indent_size=2, whitespac
logFile.write("*** " + orig_filename + ":" + str(stream.line_nr) +
(": auto indentation and whitespace formatting failed due to 132 chars limit, line should be splitted. ***\n"))
if debug:
print(' ' * ind_use + line)
# no indentation of blank lines
sys.stderr.write(' ' * ind_use + line + '\n')
# no indentation of semicolon separated lines
if re.search(r";\s*$", f_line, RE_FLAGS):
do_indent = False
use_same_line = True
else:
do_indent = True
use_same_line = False
# rm subsequent blank lines
skip_blank = is_empty and not any(comments)

View file

@ -11,7 +11,7 @@ specialRepl = None
def replaceWords(infile, outfile, replacements=repl,
specialReplacements=specialRepl,
logFile=sys.stdout):
logFile=sys.stderr):
"""Replaces the words in infile writing the output to outfile.
replacements is a dictionary with the words to replace.

View file

@ -66,7 +66,7 @@ def upcaseOMP(line):
return toUpcaseOMPRe.sub(lambda match: match.group("toUpcase").upper(), line)
def upcaseKeywords(infile, outfile, upcase_omp, logFile=sys.stdout):
def upcaseKeywords(infile, outfile, upcase_omp, logFile=sys.stderr):
"""Writes infile to outfile with all the fortran keywords upcased"""
while 1:
line = infile.readline()
@ -79,7 +79,7 @@ def upcaseKeywords(infile, outfile, upcase_omp, logFile=sys.stdout):
outfile.write(line)
def prettifyFile(infile, normalize_use, decl_linelength, decl_offset,
def prettifyFile(infile, filename, normalize_use, decl_linelength, decl_offset,
reformat, indent, whitespace, upcase_keywords,
upcase_omp, replace, logFile):
"""prettifyes the fortran source in infile into a temporary file that is
@ -91,7 +91,7 @@ def prettifyFile(infile, normalize_use, decl_linelength, decl_offset,
does not close the input file"""
ifile = infile
orig_filename = infile.name
orig_filename = filename
tmpfile = None
max_pretty_iter = 5
n_pretty_iter = 0
@ -151,19 +151,34 @@ def prettifyFile(infile, normalize_use, decl_linelength, decl_offset,
raise
def prettfyInplace(fileName, bkDir, **kwargs):
def prettfyInplace(fileName, bkDir=None, stdout=False, **kwargs):
"""Same as prettify, but inplace, replaces only if needed"""
if not os.path.exists(bkDir):
if fileName == 'stdin':
infile = os.tmpfile()
infile.write(sys.stdin.read())
else:
infile = open(fileName, 'r')
if stdout:
outfile = prettifyFile(infile=infile, filename=fileName, **kwargs)
outfile.seek(0)
sys.stdout.write(outfile.read())
outfile.close()
return
if bkDir and not os.path.exists(bkDir):
os.mkdir(bkDir)
if not os.path.isdir(bkDir):
if bkDir and not os.path.isdir(bkDir):
raise Error("bk-dir must be a directory, was " + bkDir)
infile = open(fileName, 'r')
outfile = prettifyFile(infile=infile, **kwargs)
outfile = prettifyFile(infile=infile, filename=fileName, **kwargs)
if (infile == outfile):
return
infile.seek(0)
outfile.seek(0)
same = 1
while 1:
l1 = outfile.readline()
l2 = infile.readline()
@ -173,52 +188,50 @@ def prettfyInplace(fileName, bkDir, **kwargs):
if not l1:
break
if (not same):
bkName = os.path.join(bkDir, os.path.basename(fileName))
bName = bkName
i = 0
while os.path.exists(bkName):
i += 1
bkName = bName + "." + str(i)
bkFile = None
if bkDir:
bkName = os.path.join(bkDir, os.path.basename(fileName))
bName = bkName
i = 0
while os.path.exists(bkName):
i += 1
bkName = bName + "." + str(i)
bkFile = file(bkName, "w")
infile.seek(0)
bkFile = file(bkName, "w")
while 1:
l1 = infile.readline()
if not l1:
break
bkFile.write(l1)
bkFile.close()
if bkFile:
bkFile.write(infile.read())
bkFile.close()
outfile.seek(0)
newFile = file(fileName, 'w')
while 1:
l1 = outfile.readline()
if not l1:
break
newFile.write(l1)
newFile.write(outfile.read())
newFile.close()
infile.close()
outfile.close()
def main(argv):
# future defaults
def main(argv=None):
if argv is None:
argv = sys.argv
defaultsDict = {'upcase': 1, 'normalize-use': 1, 'omp-upcase': 1,
'decl-linelength': 100, 'decl-offset': 50,
'reformat': 1, 'indent': 3, 'whitespace': 1,
'replace': 1,
'backup-dir': 'preprettify'}
'stdout': 0,
'do-backup': 0,
'backup-dir': 'preprettify',
'report-errors': 1}
usageDesc = ("usage:\n" + argv[0] + """
usageDesc = ("usage:\nfprettify" +"""
[--[no-]upcase] [--[no-]normalize-use] [--[no-]omp-upcase] [--[no-]replace]
[--[no-]reformat] --indent=3 --whitespace=1 [--help]
[--backup-dir=bk_dir] file1 [file2 ...]
[--[no-]reformat] [--indent=3] [--whitespace=1] [--help]
[--[no-]stdout] [--[no-]do-backup] [--backup-dir=bk_dir] [--[no-]report-errors] file1 [file2 ...]
Auto-format F90 source file1, file2, ...:
If no files are given, stdin is used.
--normalize-use
Sorting and alignment of variable declarations and USE statements, removal of unused list entries.
The line length of declarations is controlled by --decl-linelength=n, the offset of the variable list
is controlled by --decl-offset=n.
--upcase
Upcasing fortran keywords.
--reformat
Auto-indentation, auto-alignment and whitespace formatting.
Amount of whitespace controlled by --whitespace = 0, 1, 2.
@ -228,22 +241,32 @@ def main(argv):
- completely disable reformatting by adding a comment '!&'.
For manual formatting of a code block, use:
- start a manually formatted block with a '!&<' comment and close it with a '!&>' comment.
--upcase
Upcasing fortran keywords.
--omp-upcase
Upcasing OMP directives.
--replace
If requested the replacements performed by the replacer.py script are also performed. (FIXME: what replacements?)
If requested the replacements performed by the replacer.py script are also performed. Note: these replacements are specific to CP2K.
--stdout
write output to stdout
--[no-]do-backup
store backups of original files in backup-dir (--backup-dir option)
--[no-]report-errors
report warnings and errors
Note: for editor integration, use options --no-normalize-use --no-report-errors
Defaults:
""" + str(defaultsDict))
replace = None
if "--help" in argv:
print(usageDesc)
sys.stderr.write(usageDesc + '\n')
return(0)
args = []
for arg in argv[1:]:
m = re.match(
r"--(no-)?(normalize-use|upcase|omp-upcase|replace|reformat)", arg)
r"--(no-)?(normalize-use|upcase|omp-upcase|replace|reformat|stdout|do-backup|report-errors)", arg)
if m:
defaultsDict[m.groups()[1]] = not m.groups()[0]
else:
@ -258,53 +281,65 @@ def main(argv):
defaultsDict[m.groups()[0]] = path
else:
if arg.startswith('--'):
print('unknown option', arg)
sys.stderr.write('unknown option ' + arg + '\n')
else:
args.append(arg)
if len(args) < 1:
print(usageDesc)
else:
bkDir = ''
if defaultsDict['do-backup']:
bkDir = defaultsDict['backup-dir']
if not os.path.exists(bkDir):
# Another parallel running instance might just have created the
# dir.
try:
os.mkdir(bkDir)
except:
assert(os.path.exists(bkDir))
if not os.path.isdir(bkDir):
print("bk-dir must be a directory")
print(usageDesc)
else:
failure = 0
for fileName in args:
if not os.path.isfile(fileName):
print("file", fileName, "does not exists!")
else:
try:
prettfyInplace(fileName, bkDir=bkDir, logFile=sys.stdout,
normalize_use=defaultsDict[
'normalize-use'],
decl_linelength=defaultsDict[
'decl-linelength'],
decl_offset=defaultsDict['decl-offset'],
reformat=defaultsDict['reformat'],
indent=defaultsDict['indent'],
whitespace=defaultsDict['whitespace'],
upcase_keywords=defaultsDict['upcase'],
upcase_omp=defaultsDict['omp-upcase'],
replace=defaultsDict['replace'])
except:
failure += 1
import traceback
sys.stdout.write('-' * 60 + "\n")
traceback.print_exc(file=sys.stdout)
sys.stdout.write('-' * 60 + "\n")
sys.stdout.write(
"Processing file '" + fileName + "'\n")
return(failure > 0)
if bkDir and not os.path.exists(bkDir):
# Another parallel running instance might just have created the
# dir.
try:
os.mkdir(bkDir)
except:
assert(os.path.exists(bkDir))
if bkDir and not os.path.isdir(bkDir):
sys.stderr.write("bk-dir must be a directory" + '\n')
sys.stderr.write(usageDesc + '\n')
else:
failure = 0
if not args:
args = ['stdin']
for fileName in args:
if not os.path.isfile(fileName) and not fileName == 'stdin':
sys.stderr.write("file " + fileName + " does not exists!\n")
else:
stdout = defaultsDict['stdout'] or fileName == 'stdin'
try:
logFile = sys.stderr if defaultsDict[
'report-errors'] else open(os.devnull, "w")
prettfyInplace(fileName, bkDir=bkDir,
stdout=stdout,
logFile=logFile,
normalize_use=defaultsDict[
'normalize-use'],
decl_linelength=defaultsDict[
'decl-linelength'],
decl_offset=defaultsDict[
'decl-offset'],
reformat=defaultsDict['reformat'],
indent=defaultsDict['indent'],
whitespace=defaultsDict[
'whitespace'],
upcase_keywords=defaultsDict[
'upcase'],
upcase_omp=defaultsDict[
'omp-upcase'],
replace=defaultsDict['replace'])
except:
failure += 1
import traceback
sys.stderr.write('-' * 60 + "\n")
traceback.print_exc(file=sys.stderr)
sys.stderr.write('-' * 60 + "\n")
sys.stderr.write(
"Processing file '" + fileName + "'\n")
return(failure > 0)
#=========================================================================
def run_selftest():
# create temporary file with example code
fn = os.path.join(tempfile.gettempdir(), "prettify_selftest.F")
@ -315,15 +350,15 @@ def run_selftest():
# call prettify
rtn = main([sys.argv[0], fn])
assert(rtn==0)
assert(rtn == 0)
# check if file was altered
result = open(fn).read()
for i, (l1, l2) in enumerate(zip(result.split("\n"), ref.split("\n"))):
if(l1 != l2):
print("Error: Line %d is not invariant."%i)
print("before: "+l1)
print("after : "+l2)
print("Error: Line %d is not invariant." % i)
print("before: " + l1)
print("after : " + l2)
os.remove(fn)
return(1)
@ -336,7 +371,7 @@ if(__name__ == '__main__'):
if(len(sys.argv) == 2 and sys.argv[-1] == "--selftest"):
rtn = run_selftest()
else:
rtn = main(sys.argv)
rtn = main()
sys.exit(rtn)
# EOF

15
tools/prettify/setup.py Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env python
from setuptools import setup
setup(name='fprettify',
description='auto-formatter for modern fortran source code',
author='Mohamed Fawzi, Patrick Seewald',
license = "GPL",
entry_points={'console_scripts': ['fprettify = fprettify:main']},
py_modules=['fprettify',
'formatting.normalizeFortranFile',
'formatting.reformatFortranFile',
'formatting.replacer',
'formatting.selftest']
)