Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 30 additions & 29 deletions scripts/fortran_tools/fortran_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ class FortranWriter:
###########################################################################
# Class variables
###########################################################################
__INDENT = 3 # Spaces per indent level
__INDENT = 2 # Spaces per indent level

__CONTINUE_INDENT = 5 # Extra spaces on continuation line
__CONTINUE_INDENT = 4 # Extra spaces on continuation line

__LINE_FILL = 97 # Target line length

__LINE_MAX = 130 # Max line length
__LINE_MAX = 120 # Max line length (for Codee)

__BREAK_CHARS = [',', '+', '*', '/', '(', ')']

# CCPP copyright statement to be included in all generated Fortran files
__COPYRIGHT = '''!
Expand All @@ -38,8 +40,7 @@ class FortranWriter:
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
! THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
! IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'''
! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.'''

__MOD_HEADER = '''
!>
Expand All @@ -52,7 +53,7 @@ class FortranWriter:
__MOD_PREAMBLE = ["implicit none", "private"]

__CONTAINS = '''
CONTAINS'''
contains'''

__MOD_FOOTER = '''
end module {module}'''
Expand Down Expand Up @@ -140,18 +141,12 @@ def write(self, statement, indent_level, continue_line=False):
ostmt = statement.strip()
is_comment_stmt = ostmt and (ostmt[0] == '!')
in_comment = ""
if ostmt and (ostmt[0] != '&'):
# Skip indent for continue that is in the middle of a
# token or a quoted region
outstr = istr + ostmt
else:
outstr = ostmt
# end if
outstr = istr + ostmt
line_len = len(outstr)
if line_len > self.__line_fill:
# Collect pretty break points
spaces = list()
commas = list()
spaces = []
break_chars = []
sptr = len(istr)
in_single_char = False
in_double_char = False
Expand Down Expand Up @@ -180,12 +175,12 @@ def write(self, statement, indent_level, continue_line=False):
elif outstr[sptr] == ' ':
# Non-quote spaces are where we can break
spaces.append(sptr)
elif outstr[sptr] == ',':
# Non-quote commas are where we can break
commas.append(sptr)
elif outstr[sptr:sptr+2] == '//':
# Non-quote commas are where we can break
commas.append(sptr + 1)
# Non-quote syntax are where we can break
break_chars.append(sptr + 1)
elif outstr[sptr] in FortranWriter.__BREAK_CHARS:
# Non-quote syntax are where we can break
break_chars.append(sptr)
# End if (no else, other characters will be ignored)
sptr = sptr + 1
# End while
Expand All @@ -203,7 +198,7 @@ def write(self, statement, indent_level, continue_line=False):
# end if
best = self.find_best_break(spaces)
if best >= self.__line_fill:
best = min(best, self.find_best_break(commas))
best = min(best, self.find_best_break(break_chars))
# End if
line_continue = False
if best >= self.__line_max:
Expand All @@ -216,10 +211,13 @@ def write(self, statement, indent_level, continue_line=False):
# end if
if len(outstr) > best:
if self._in_quote(outstr[0:best+1]):
if best >= FortranWriter.__LINE_MAX - 1:
best = FortranWriter.__LINE_MAX - 2
# end if
line_continue = '&'
elif not outstr[best+1:].lstrip():
# If the next line is empty, the current line is done
# and is equal to the max line length. Do not use
# If the next line is empty, the current line is done
# and is equal to the max line length. Do not use
# continue and set best to line_max (best+1)
line_continue = False
best = best+1
Expand All @@ -233,24 +231,27 @@ def write(self, statement, indent_level, continue_line=False):
if in_comment or is_comment_stmt:
line_continue = False
# end if
if line_continue:
fill = "{}&".format((self.__line_fill - best)*' ')
if line_continue == '&':
fill = '&'
elif line_continue:
fill = ' &'
else:
fill = ""
# End if
outline = f"{outstr[0:best+1]}{fill}".rstrip()
outline = f"{outstr[0:best+1].rstrip()}{fill}"
self.__file.write(f"{outline}\n")
if best <= 0:
imsg = "Internal ERROR: Unable to break line"
raise ValueError(f"{imsg}, '{statement}'")
# end if
statement = in_comment + outstr[best+1:]
if isinstance(line_continue, str) and statement:
if isinstance(line_continue, str) and statement.strip():
statement = line_continue + statement
# end if
self.write(statement, indent_level, continue_line=line_continue)
if statement.strip():
self.write(statement, indent_level, continue_line=line_continue)
else:
self.__file.write("{}\n".format(outstr))
self.__file.write(f"{outstr}\n")
# End if
# End if

Expand Down
4 changes: 2 additions & 2 deletions scripts/host_cap.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,12 +732,12 @@ def write_host_cap(host_model, api, module_name, output_dir, run_env):
cap.write("return", 4)
cap.write("end if", 3)
# Allocate the suite's dynamic constituents array
size_string = "0+"
size_string = "0 +"
for var in host_local_vars.variable_list():
vtype = var.get_prop_value('type')
if vtype == 'ccpp_constituent_properties_t':
local_name = var.get_prop_value('local_name')
size_string += f"size({local_name})+"
size_string += f"size({local_name}) +"
# end if
# end for
if not has_dyn_consts:
Expand Down
23 changes: 12 additions & 11 deletions test/unit_tests/sample_files/fortran_files/comments_test.F90
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,25 @@
! IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


!>
!! @brief Auto-generated Test of comment writing for FortranWriter
!!
!
module comments_test

! codee format off
! We can write comments in the module header
! We can write indented comments in the header
integer :: foo ! Comment at end of line works
integer :: bar !
! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
!
integer :: baz !
! yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
! yyyyy
! codee format on
! We can write indented comments in the header
integer :: foo ! Comment at end of line works
integer :: bar !
! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
!
integer :: baz !
! yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
! yyyyyyyyyyyyyy

CONTAINS
! We can write comments in the module body
contains
! We can write comments in the module body

end module comments_test
47 changes: 30 additions & 17 deletions test/unit_tests/sample_files/fortran_files/linebreak_test.F90
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,43 @@
! IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
! CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


!>
!! @brief Auto-generated Test of line breaking for FortranWriter
!!
!
module linebreak_test

character(len=7) :: data = (/ name000, name001, name002, name003, name004, name005, name006, &
name007, name008, name009, name010, name011, name012, name013, name014, name015, &
name016, name017, name018, name019, name020, name021, name022, name023, name024, &
name025, name026, name027, name028, name029, name030, name031, name032, name033, &
name034, name035, name036, name037, name038, name039, name040, name041, name042, &
name043, name044, name045, name046, name047, name048, name049, name050, name051, &
name052, name053, name054, name055, name056, name057, name058, name059, name060, &
name061, name062, name063, name064, name065, name066, name067, name068, name069, &
name070, name071, name072, name073, name074, name075, name076, name077, name078, &
name079, name080, name081, name082, name083, name084, name085, name086, name087, &
name088, name089, name090, name091, name092, name093, name094, name095, name096, &
name097, name098, name099 /)
character(len=7) :: data(100) = (/ 'name000', 'name001', 'name002', 'name003', 'name004', &
'name005', 'name006', 'name007', 'name008', 'name009', 'name010', 'name011', 'name012', &
'name013', 'name014', 'name015', 'name016', 'name017', 'name018', 'name019', 'name020', &
'name021', 'name022', 'name023', 'name024', 'name025', 'name026', 'name027', 'name028', &
'name029', 'name030', 'name031', 'name032', 'name033', 'name034', 'name035', 'name036', &
'name037', 'name038', 'name039', 'name040', 'name041', 'name042', 'name043', 'name044', &
'name045', 'name046', 'name047', 'name048', 'name049', 'name050', 'name051', 'name052', &
'name053', 'name054', 'name055', 'name056', 'name057', 'name058', 'name059', 'name060', &
'name061', 'name062', 'name063', 'name064', 'name065', 'name066', 'name067', 'name068', &
'name069', 'name070', 'name071', 'name072', 'name073', 'name074', 'name075', 'name076', &
'name077', 'name078', 'name079', 'name080', 'name081', 'name082', 'name083', 'name084', &
'name085', 'name086', 'name087', 'name088', 'name089', 'name090', 'name091', 'name092', &
'name093', 'name094', 'name095', 'name096', 'name097', 'name098', 'name099' /)

contains

CONTAINS
call &
endrun('Cannot read columns_on_task from file'// &
', columns_on_task has no horizontal dimension; columns_on_task is a protected variable')
subroutine foo(ozone_constituents, aerosol_constituents, volcaero_constituents, &
other_constituents)
integer, intent(in) :: ozone_constituents(:)
integer, intent(in) :: aerosol_constituents(:)
integer, intent(in) :: volcaero_constituents(:)
integer, intent(in) :: other_constituents(:)
real, allocatable :: tracer_data_test_dynamic_constituents(:)
! codee format off
allocate(tracer_data_test_dynamic_constituents(0+size(ozone_constituents)+size( &
aerosol_constituents)+size(volcaero_constituents)+size(other_constituents)))

write(6, '(a)') &
'Cannot read columns_on_task from file'// &
', columns_on_task has no horizontal dimension; columns_on_task is a protected variable'
! codee format on
end subroutine foo

end module linebreak_test
Loading
Loading