mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
282 lines
9.7 KiB
Python
Executable File
282 lines
9.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
"""
|
|
This script takes old-style "Whitesmiths" indented VTK source files as
|
|
input, and re-indents the braces according to the new VTK style.
|
|
Only the brace indentation is modified.
|
|
|
|
Written by David Gobbi on Sep 30, 2015.
|
|
"""
|
|
|
|
import sys
|
|
import re
|
|
|
|
def reindent(filename):
|
|
"""Reindent a file from Whitesmiths style to Allman style"""
|
|
|
|
# This first part of this function clears all strings and comments
|
|
# where non-grammatical braces might be hiding.
|
|
|
|
keychar = re.compile(r"""[/"']""")
|
|
c_comment = re.compile(r"\/\*(\*(?!\/)|[^*])*\*\/")
|
|
c_comment_start = re.compile(r"\/\*(\*(?!\/)|[^*])*$")
|
|
c_comment_end = re.compile(r"^(\*(?!\/)|[^*])*\*\/")
|
|
cpp_comment = re.compile(r"\/\/.*")
|
|
string_literal = re.compile(r'"([^\\"]|\\.)*"')
|
|
string_literal_start = re.compile(r'"([^\\"]|\\.)*\\$')
|
|
string_literal_end = re.compile(r'^([^\\"]|\\.)*"')
|
|
char_literal = re.compile(r"'([^\\']|\\.)*'")
|
|
char_literal_start = re.compile(r"'([^\\']|\\.)*\\$")
|
|
char_literal_end = re.compile(r"^([^\\']|\\.)*'")
|
|
|
|
try:
|
|
f = open(filename)
|
|
lines = f.readlines()
|
|
f.close()
|
|
except:
|
|
sys.stderr.write(filename + ": ")
|
|
sys.stderr.write(str(sys.exc_info()[1]) + "\n")
|
|
sys.exit(1)
|
|
|
|
n = len(lines)
|
|
newlines = []
|
|
|
|
cont = None
|
|
|
|
for i in range(n):
|
|
line = lines[i].rstrip()
|
|
if cont is not None:
|
|
match = cont.match(line)
|
|
if match:
|
|
line = line[match.end():]
|
|
cont = None
|
|
else:
|
|
if cont is c_comment_end:
|
|
newlines.append("")
|
|
continue
|
|
else:
|
|
newlines.append('\\')
|
|
continue
|
|
|
|
pos = 0
|
|
while True:
|
|
match = keychar.search(line, pos)
|
|
if match is None:
|
|
break
|
|
pos = match.start()
|
|
end = match.end()
|
|
match = c_comment.match(line, pos)
|
|
if match:
|
|
line = line[0:pos] + " " + line[match.end():]
|
|
pos += 1
|
|
continue
|
|
match = c_comment_start.match(line, pos)
|
|
if match:
|
|
if line[-1] == '\\':
|
|
line = line[0:pos] + ' \\'
|
|
else:
|
|
line = line[0:pos]
|
|
cont = c_comment_end
|
|
break
|
|
match = cpp_comment.match(line, pos)
|
|
if match:
|
|
if line[-1] == '\\':
|
|
line = line[0:pos] + ' \\'
|
|
else:
|
|
line = line[0:pos]
|
|
break
|
|
match = string_literal.match(line, pos)
|
|
if match:
|
|
line = line[0:pos] + "\"\"" + line[match.end():]
|
|
pos += 2
|
|
continue
|
|
match = string_literal_start.match(line, pos)
|
|
if match:
|
|
line = line[0:pos] + "\"\"\\"
|
|
cont = string_literal_end
|
|
break
|
|
match = char_literal.match(line, pos)
|
|
if match:
|
|
line = line[0:pos] + "\' \'" + line[match.end():]
|
|
pos += 3
|
|
continue
|
|
match = char_literal_start.match(line, pos)
|
|
if match:
|
|
line = line[0:pos] + "\' \'\\"
|
|
cont = char_literal_end
|
|
break
|
|
pos += 1
|
|
|
|
newlines.append(line.rstrip())
|
|
|
|
# all changes go through this function
|
|
lines_changed = {}
|
|
def changeline(i, newtext, lines_changed=lines_changed):
|
|
if newtext != lines[i]:
|
|
lines[i] = newtext
|
|
lines_changed[i] = newtext
|
|
|
|
# Use a stack to keep track of braces and, whenever a closing brace is
|
|
# found, properly indent it and its opening brace.
|
|
# For #if directives, check whether there are mismatched braces within
|
|
# the conditional block, and if so, print a warning and reset the stack
|
|
# to the depth that it had at the start of the block.
|
|
|
|
# stack holds tuples (delim, row, col, newcol)
|
|
stack = []
|
|
lastdepth = 0
|
|
|
|
# save the stack for conditional compilation blocks
|
|
dstack = []
|
|
|
|
directive = re.compile(r" *# *(..)")
|
|
label = re.compile(r""" *(case *)?(' '|""|[A-Za-z0-9_]| *:: *)+ *:$""")
|
|
delims = re.compile(r"[{}()\[\]]")
|
|
spaces = re.compile(r" *")
|
|
cplusplus = re.compile(r" *# *ifdef *__cplusplus")
|
|
|
|
lastpos = 0
|
|
newpos = 0
|
|
continuation = False
|
|
new_context = True
|
|
in_else = False
|
|
in_define = False
|
|
in_assign = False
|
|
leaving_define = False
|
|
save_stack = None
|
|
|
|
for i in range(n):
|
|
line = newlines[i]
|
|
pos = 0
|
|
|
|
# restore stack when leaving #define
|
|
if leaving_define:
|
|
stack, lastpos, newpos, continuation = save_stack
|
|
save_stack = None
|
|
in_define = False
|
|
leaving_define = False
|
|
|
|
# handle #if conditionals
|
|
is_directive = False
|
|
in_else = False
|
|
match = directive.match(line)
|
|
if match:
|
|
is_directive = True
|
|
if match.groups()[0] == 'if':
|
|
dstack.append((list(stack), line))
|
|
elif match.groups()[0] in ('en', 'el'):
|
|
oldstack, dline = dstack.pop()
|
|
if len(stack) > len(oldstack) and not cplusplus.match(dline):
|
|
sys.stderr.write(filename + ":" + str(i) + ": ")
|
|
sys.stderr.write("mismatched delimiter in \"" +
|
|
dline + "\" block\n")
|
|
if match.groups()[0] == 'el':
|
|
in_else = True
|
|
stack = oldstack
|
|
dstack.append((list(stack), line))
|
|
elif match.groups()[0] == 'de':
|
|
in_define = True
|
|
leaving_define = False
|
|
save_stack = (stack, lastpos, newpos, continuation)
|
|
stack = []
|
|
new_context = True
|
|
|
|
# remove backslash at end of line, if present
|
|
if len(line) > 0 and line[-1] == '\\':
|
|
line = line[0:-1].rstrip()
|
|
elif in_define:
|
|
leaving_define = True
|
|
|
|
if not is_directive and len(line) > 0 and not continuation:
|
|
# what is the indentation of the current line?
|
|
match = spaces.match(line)
|
|
newpos = match.end()
|
|
|
|
# all statements end with ':', ';', '{', or '}'
|
|
if len(line) > 0:
|
|
if (new_context or line[-1] in ('{', '}', ';') or
|
|
(label.match(line) and not continuation)):
|
|
continuation = False
|
|
new_context = False
|
|
elif not is_directive:
|
|
continuation = True
|
|
|
|
# search for braces
|
|
while True:
|
|
match = delims.search(line, pos)
|
|
if match is None:
|
|
break
|
|
pos = match.start()
|
|
delim = line[pos]
|
|
if delim in ('(', '['):
|
|
# save delim, row, col, and current indentation
|
|
stack.append((delim, i, pos, newpos))
|
|
elif delim == '{':
|
|
if in_assign:
|
|
# do not adjust braces for initializer lists
|
|
stack.append((delim, i, pos, pos))
|
|
elif ((in_else or in_define) and spaces.sub("", line) == "{"):
|
|
# for opening braces that might have no match
|
|
indent = " "*lastpos
|
|
changeline(i, spaces.sub(indent, lines[i], count=1))
|
|
stack.append((delim, i, lastpos, lastpos))
|
|
else:
|
|
# save delim, row, col, and previous indentation
|
|
stack.append((delim, i, pos, lastpos))
|
|
newpos = pos + 2
|
|
lastpos = newpos
|
|
else:
|
|
# found a ')', ']', or '}' delimiter, so pop its partner
|
|
try:
|
|
ldelim, j, k, newpos = stack.pop()
|
|
except IndexError:
|
|
ldelim = ""
|
|
if ldelim != {'}':'{', ')':'(', ']':'['}[delim]:
|
|
sys.stderr.write(filename + ":" + str(i) + ": ")
|
|
sys.stderr.write("mismatched \'" + delim + "\'\n")
|
|
# adjust the indentation of matching '{', '}'
|
|
if (ldelim == '{' and delim == '}' and
|
|
spaces.sub("", lines[i][0:pos]) == "" and
|
|
spaces.sub("", lines[j][0:k]) == ""):
|
|
indent = " "*newpos
|
|
changeline(i, spaces.sub(indent, lines[i], count=1))
|
|
changeline(j, spaces.sub(indent, lines[j], count=1))
|
|
pos += 1
|
|
|
|
# check for " = " and #define assignments for the sake of
|
|
# the { inializer list } that might be on the following line
|
|
if len(line) > 0:
|
|
if (line[-1] == '=' or
|
|
(is_directive and in_define and not leaving_define)):
|
|
in_assign = True
|
|
elif not is_directive:
|
|
in_assign = False
|
|
|
|
lastpos = newpos
|
|
|
|
if len(dstack) != 0:
|
|
sys.stderr.write(filename + ": ")
|
|
sys.stderr.write("mismatched #if conditional.\n")
|
|
|
|
if len(stack) != 0:
|
|
sys.stderr.write(filename + ":" + str(stack[0][1]) + ": ")
|
|
sys.stderr.write("no match for " + stack[0][0] +
|
|
" before end of file.\n")
|
|
|
|
if lines_changed:
|
|
# remove any trailing whitespace
|
|
trailing = re.compile(r" *$")
|
|
for i in range(n):
|
|
lines[i] = trailing.sub("", lines[i])
|
|
while n > 0 and lines[n-1].rstrip() == "":
|
|
n -= 1
|
|
# rewrite the file
|
|
ofile = open(filename, 'w')
|
|
ofile.writelines(lines)
|
|
ofile.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
for filename in sys.argv[1:]:
|
|
reindent(filename)
|