38 ''' Provides support for breaking long fortran lines into smaller ones
39 to allow the code to conform to the maximum line length limits (132
40 for f90 free format is the default)'''
47 def find_break_point(line, max_index, key_list):
48 ''' Finds the most appropriate line break point for the Fortran code in
51 :param str line: the Fortran code string to find the line break point for.
52 :param int max_index: the maximum index in line to search for the line
54 :param key_list: list of potential symbols to break the line at. The
55 members of the list early in the ordering have priority
56 for breaking the line, i.e. if the list contains multiple
57 elements, any possible position of the first element will
58 be found before trying any other element of the list.
59 :type key_list: List[str]
61 :returns: index to break the line into multiple lines.
64 :raises InternalError: if no suitable break point is found in line.
68 first_non_whitespace = len(line) - len(line.lstrip())
70 idx = line.rfind(key, first_non_whitespace+1, max_index)
74 f
"Error in find_break_point. No suitable break point found"
75 f
" for line '{line[:max_index]}' and keys '{str(key_list)}'")
80 ''' This class take a free format fortran code as a string and
81 line wraps any lines that are larger than the specified line
85 def __init__(self, line_length=132):
88 "openmp_directive":
"!$omp& ",
89 "openacc_directive":
"!$acc& ",
92 self.
_cont_end_cont_end = {
"statement":
"&",
93 "openmp_directive":
" &",
94 "openacc_directive":
" &",
97 self.
_key_lists_key_lists = {
"statement": [
", ",
",",
" "],
98 "openmp_directive": [
" ",
",",
")",
"="],
99 "openacc_directive": [
" ",
",",
")",
"="],
100 "comment": [
" ",
".",
","],
101 "unknown": [
" ",
",",
"=",
"+",
")"]}
102 self.
_stat_stat = re.compile(
r'^\s*(INTEGER|REAL|TYPE|CALL|SUBROUTINE|USE)',
104 self.
_omp_omp = re.compile(
r'^\s*!\$OMP', flags=re.I)
105 self.
_acc_acc = re.compile(
r'^\s*!\$ACC', flags=re.I)
106 self.
_comment_comment = re.compile(
r'^\s*!')
109 '''returns true if at least one of the lines in the input code is
110 longer than the allowed length. Otherwise returns false '''
111 for line
in fortran_in.split(
'\n'):
118 ''' returns the maximum allowed line length'''
122 ''' Processes unlimited line-length Fortran code into Fortran
123 code with long lines wrapped appropriately.
125 :param str fortran_in: Fortran code to be line wrapped.
127 :returns: line wrapped Fortran code.
132 for line
in fortran_in.split(
'\n'):
137 c_end = self.
_cont_end_cont_end[line_type]
138 key_list = self.
_key_lists_key_lists[line_type]
141 break_point = find_break_point(
142 line, self.
_line_length_line_length-len(c_end), key_list)
143 except InternalError:
148 fortran_out += line +
"\n"
150 break_point = find_break_point(
151 line, self.
_line_length_line_length-len(c_end), key_list)
153 fortran_out += line[:break_point] + c_end +
"\n"
154 line = line[break_point:]
155 while len(line) + len(c_start) > self.
_line_length_line_length:
156 break_point = find_break_point(
157 line, self.
_line_length_line_length-len(c_end)-len(c_start),
159 fortran_out += c_start + line[:break_point] + c_end +
"\n"
160 line = line[break_point:]
162 fortran_out += c_start + line +
"\n"
164 fortran_out += line +
"\n"
167 return fortran_out[:-1]
169 def _get_line_type(self, line):
170 ''' Classes lines into diffrent types. This is required as
171 directives need different continuation characters to fortran
172 statements. It also enables us to know a little about the
173 structure of the line which could be useful at some point.'''
175 if self.
_stat_stat.match(line):
177 if self.
_omp_omp.match(line):
178 return "openmp_directive"
179 if self.
_acc_acc.match(line):
180 return "openacc_directive"
181 if self.
_comment_comment.match(line):
def process(self, fortran_in)
def _get_line_type(self, line)
def long_lines(self, fortran_in)