Skip to content

Commit 11328d4

Browse files
committed
Set INPUT_STR_LENGTH to 1024
Now that INPUT_STR_LENGTH is only used as the size of a single temporary character string, the maximum permitted line length can be increased to a larger value without unduly impacting the memory footprint of the model, so it has been increased to 1024. If this is not large enough, considering that MOM6 also supports line continuation, there is a bigger problem than this limit. Some message strings were also changed to be allocatable, while others have sizes that are set using param_file_type%max_line_len. Also eliminated the hard-coded internal parameter all_PEs_read, which had a note that it should have been eliminated in about 2010 (before MOM6 existed). All answers and output are bitwise identical.
1 parent 5ee5dae commit 11328d4

File tree

1 file changed

+38
-52
lines changed

1 file changed

+38
-52
lines changed

src/framework/MOM_file_parser.F90

+38-52
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ module MOM_file_parser
1616

1717
implicit none ; private
1818

19+
! These are hard-coded limits that are used in the following code. They should be set
20+
! generously enough not to impose any significant limitations.
1921
integer, parameter, public :: MAX_PARAM_FILES = 5 !< Maximum number of parameter files.
20-
integer, parameter :: INPUT_STR_LENGTH = 320 !< Maximum line length in parameter file.
21-
integer, parameter :: FILENAME_LENGTH = 200 !< Maximum number of characters in file names.
22+
integer, parameter :: INPUT_STR_LENGTH = 1024 !< Maximum line length in parameter file. Lines that
23+
!! are combined by ending in '\' or '&' can exceed
24+
!! this limit after merging.
25+
integer, parameter :: FILENAME_LENGTH = 200 !< Maximum number of characters in file names.
2226

23-
! The all_PEs_read option should be eliminated with post-riga shared code.
24-
logical :: all_PEs_read = .false. !< If true, all PEs read the input files
25-
!! TODO: Eliminate this parameter
2627

2728
!>@{ Default values for parameters
2829
logical, parameter :: report_unused_default = .true.
@@ -138,7 +139,6 @@ subroutine open_param_file(filename, CS, checkable, component, doc_file_dir)
138139
logical :: file_exists, unit_in_use, Netcdf_file, may_check, reopened_file
139140
integer :: ios, iounit, strlen, i
140141
character(len=240) :: doc_path
141-
character(len=16) :: sub_string
142142
type(parameter_block), pointer :: block => NULL()
143143

144144
may_check = .true. ; if (present(checkable)) may_check = checkable
@@ -183,11 +183,10 @@ subroutine open_param_file(filename, CS, checkable, component, doc_file_dir)
183183
if (Netcdf_file) &
184184
call MOM_error(FATAL,"open_param_file: NetCDF files are not yet supported.")
185185

186-
if (all_PEs_read .or. is_root_pe()) then
186+
if (is_root_pe()) then
187187
open(newunit=iounit, file=trim(filename), access='SEQUENTIAL', &
188188
form='FORMATTED', action='READ', position='REWIND', iostat=ios)
189-
if (ios /= 0) call MOM_error(FATAL, "open_param_file: Error opening '"// &
190-
trim(filename)//"'.")
189+
if (ios /= 0) call MOM_error(FATAL, "open_param_file: Error opening '"//trim(filename)//"'.")
191190
else
192191
iounit = 1
193192
endif
@@ -202,15 +201,11 @@ subroutine open_param_file(filename, CS, checkable, component, doc_file_dir)
202201
if (associated(CS%blockName)) deallocate(CS%blockName)
203202
allocate(block) ; block%name = '' ; CS%blockName => block
204203

205-
call MOM_mesg("open_param_file: "// trim(filename)// &
206-
" has been opened successfully.", 5)
204+
call MOM_mesg("open_param_file: "// trim(filename)//" has been opened successfully.", 5)
207205

208206
call populate_param_data(iounit, filename, CS%param_data(i))
209207
! Increment the maximum line length, but always report values in blocks of 4 characters.
210208
CS%max_line_len = max(CS%max_line_len, 4 + 4*(max_input_line_length(CS, i) - 1) / 4)
211-
write (sub_string, '(i4.4)') CS%max_line_len
212-
call MOM_mesg("open_param_file: Maximum input line length determined to be "//&
213-
trim(adjustl(sub_string))//" characters.", 5)
214209

215210
call read_param(CS,"SEND_LOG_TO_STDOUT",CS%log_to_stdout)
216211
call read_param(CS,"REPORT_UNUSED_PARAMS",CS%report_unused)
@@ -264,7 +259,7 @@ subroutine close_param_file(CS, quiet_close, component)
264259

265260
if (present(quiet_close)) then ; if (quiet_close) then
266261
do i = 1, CS%nfiles
267-
if (all_PEs_read .or. is_root_pe()) close(CS%iounit(i))
262+
if (is_root_pe()) close(CS%iounit(i))
268263
call MOM_mesg("close_param_file: "// trim(CS%filename(i))// &
269264
" has been closed successfully.", 5)
270265
CS%iounit(i) = -1
@@ -334,9 +329,8 @@ subroutine close_param_file(CS, quiet_close, component)
334329
enddo
335330
endif
336331

337-
if (all_PEs_read .or. is_root_pe()) close(CS%iounit(i))
338-
call MOM_mesg("close_param_file: "// trim(CS%filename(i))// &
339-
" has been closed successfully.", 5)
332+
if (is_root_pe()) close(CS%iounit(i))
333+
call MOM_mesg("close_param_file: "// trim(CS%filename(i))//" has been closed successfully.", 5)
340334
CS%iounit(i) = -1
341335
CS%filename(i) = ''
342336
CS%NetCDF_file(i) = .false.
@@ -369,11 +363,8 @@ subroutine populate_param_data(iounit, filename, param_data)
369363
integer :: n, num_lines, total_chars, ch, rsc, llen, int_buf(2)
370364
logical :: inMultiLineComment
371365

372-
character(len=80) :: frag1, frag2
373-
374-
375366
! Find the number of keyword lines in a parameter file
376-
if (all_PEs_read .or. is_root_pe()) then
367+
if (is_root_pe()) then
377368
! rewind the parameter file
378369
rewind(iounit)
379370

@@ -408,19 +399,17 @@ subroutine populate_param_data(iounit, filename, param_data)
408399
endif ! (is_root_pe())
409400

410401
! Broadcast the number of valid entries in parameter file
411-
if (.not. all_PEs_read) then
412-
call broadcast(int_buf, 2, root_pe())
413-
num_lines = int_buf(1)
414-
total_chars = int_buf(2)
415-
endif
402+
call broadcast(int_buf, 2, root_pe())
403+
num_lines = int_buf(1)
404+
total_chars = int_buf(2)
416405

417406
! Set up the space for storing the actual lines.
418407
param_data%num_lines = num_lines
419408
allocate (line_len(num_lines), source=0)
420409
allocate (char_buf(total_chars), source=" ")
421410

422411
! Read the actual lines.
423-
if (all_PEs_read .or. is_root_pe()) then
412+
if (is_root_pe()) then
424413
! rewind the parameter file
425414
rewind(iounit)
426415

@@ -435,6 +424,10 @@ subroutine populate_param_data(iounit, filename, param_data)
435424
else
436425
if (lastNonCommentNonBlank(line)>0) then
437426
line = removeComments(line)
427+
if ((len_trim(line) > 1000) .and. is_root_PE()) then
428+
call MOM_error(WARNING, "MOM_file_parser: Consider using continuation to split up "//&
429+
"the excessivley long parameter input line "//trim(line))
430+
endif
438431
line = simplifyWhiteSpace(line(:len_trim(line)))
439432
num_lines = num_lines + 1
440433
llen = len_trim(line)
@@ -453,10 +446,8 @@ subroutine populate_param_data(iounit, filename, param_data)
453446
endif ! (is_root_pe())
454447

455448
! Broadcast the populated arrays line_len and char_buf
456-
if (.not. all_PEs_read) then
457-
call broadcast(line_len, num_lines, root_pe())
458-
call broadcast(char_buf(1:total_chars), 1, root_pe())
459-
endif
449+
call broadcast(line_len, num_lines, root_pe())
450+
call broadcast(char_buf(1:total_chars), 1, root_pe())
460451

461452
! Allocate space to hold contents of the parameter file, including the lines in param_data%fln
462453
allocate(param_data%fln(num_lines))
@@ -767,8 +758,7 @@ subroutine read_param_char(CS, varname, value, fail_if_missing)
767758
if (found) then
768759
value = trim(strip_quotes(value_string(1)))
769760
elseif (present(fail_if_missing)) then ; if (fail_if_missing) then
770-
call MOM_error(FATAL,'Unable to find variable '//trim(varname)// &
771-
' in any input files.')
761+
call MOM_error(FATAL, 'Unable to find variable '//trim(varname)//' in any input files.')
772762
endif ; endif
773763

774764
end subroutine read_param_char
@@ -805,8 +795,7 @@ subroutine read_param_char_array(CS, varname, value, fail_if_missing)
805795
endif
806796
do i=i_out,SIZE(value) ; value(i) = " " ; enddo
807797
elseif (present(fail_if_missing)) then ; if (fail_if_missing) then
808-
call MOM_error(FATAL,'Unable to find variable '//trim(varname)// &
809-
' in any input files.')
798+
call MOM_error(FATAL, 'Unable to find variable '//trim(varname)//' in any input files.')
810799
endif ; endif
811800

812801
end subroutine read_param_char_array
@@ -829,8 +818,7 @@ subroutine read_param_logical(CS, varname, value, fail_if_missing)
829818
if (found) then
830819
value = defined
831820
elseif (present(fail_if_missing)) then ; if (fail_if_missing) then
832-
call MOM_error(FATAL,'Unable to find variable '//trim(varname)// &
833-
' in any input files.')
821+
call MOM_error(FATAL, 'Unable to find variable '//trim(varname)//' in any input files.')
834822
endif ; endif
835823
end subroutine read_param_logical
836824

@@ -891,11 +879,9 @@ subroutine read_param_time(CS, varname, value, timeunit, fail_if_missing, date_f
891879
else
892880
if (present(fail_if_missing)) then ; if (fail_if_missing) then
893881
if (.not.found) then
894-
call MOM_error(FATAL,'Unable to find variable '//trim(varname)// &
895-
' in any input files.')
882+
call MOM_error(FATAL, 'Unable to find variable '//trim(varname)//' in any input files.')
896883
else
897-
call MOM_error(FATAL,'Variable '//trim(varname)// &
898-
' found but not set in input files.')
884+
call MOM_error(FATAL, 'Variable '//trim(varname)//' found but not set in input files.')
899885
endif
900886
endif ; endif
901887
endif
@@ -907,7 +893,7 @@ end subroutine read_param_time
907893

908894
!> This function removes single and double quotes from a character string
909895
function strip_quotes(val_str)
910-
character(len=*) :: val_str !< The character string to work on
896+
character(len=*), intent(in) :: val_str !< The character string to work on
911897
character(len=len(val_str)) :: strip_quotes
912898
! Local variables
913899
integer :: i
@@ -939,7 +925,6 @@ function max_input_line_length(CS, pf_num) result(max_len)
939925

940926
! Local variables
941927
character(len=FILENAME_LENGTH) :: filename
942-
! character(len=:), allocatable :: line
943928
character :: last_char
944929
integer :: ipf, ipf_s, ipf_e
945930
integer :: last, last1, line_len, count, contBufSize
@@ -1003,7 +988,8 @@ subroutine get_variable_line(CS, varname, found, defined, value_string, paramIsL
1003988

1004989
! Local variables
1005990
character(len=CS%max_line_len) :: val_str, lname, origLine
1006-
character(len=CS%max_line_len) :: line, continuationBuffer, blockName
991+
character(len=CS%max_line_len) :: line, continuationBuffer
992+
character(len=240) :: blockName
1007993
character(len=FILENAME_LENGTH) :: filename
1008994
integer :: is, id, isd, isu, ise, iso, ipf
1009995
integer :: last, last1, ival, oval, max_vals, count, contBufSize
@@ -1407,7 +1393,7 @@ subroutine log_param_int_array(CS, modulename, varname, value, desc, &
14071393
logical, optional, intent(in) :: like_default !< If present and true, log this parameter as
14081394
!! though it has the default value, even if there is no default.
14091395

1410-
character(len=1320) :: mesg
1396+
character(len=CS%max_line_len+120) :: mesg
14111397
character(len=240) :: myunits
14121398

14131399
write(mesg, '(" ",a," ",a,": ",A)') trim(modulename), trim(varname), trim(left_ints(value))
@@ -1549,16 +1535,16 @@ subroutine log_param_char(CS, modulename, varname, value, desc, units, &
15491535
logical, optional, intent(in) :: like_default !< If present and true, log this parameter as
15501536
!! though it has the default value, even if there is no default.
15511537

1552-
character(len=1024) :: mesg, myunits
1538+
character(len=:), allocatable :: mesg
1539+
character(len=240) :: myunits
15531540

1554-
write(mesg, '(" ",a," ",a,": ",a)') &
1555-
trim(modulename), trim(varname), trim(value)
1541+
mesg = " " // trim(modulename) // " " // trim(varname) // ": " // trim(value)
15561542
if (is_root_pe()) then
15571543
if (CS%log_open) write(CS%stdlog,'(a)') trim(mesg)
15581544
if (CS%log_to_stdout) write(CS%stdout,'(a)') trim(mesg)
15591545
endif
15601546

1561-
myunits=" "; if (present(units)) write(myunits(1:1024),'(A)') trim(units)
1547+
myunits=" "; if (present(units)) write(myunits(1:240),'(A)') trim(units)
15621548
if (present(desc)) &
15631549
call doc_param(CS%doc, varname, desc, myunits, value, default, &
15641550
layoutParam=layoutParam, debuggingParam=debuggingParam, like_default=like_default)
@@ -1936,7 +1922,7 @@ subroutine get_param_char_array(CS, modulename, varname, value, desc, units, &
19361922
! Local variables
19371923
logical :: do_read, do_log
19381924
integer :: i, len_tot, len_val
1939-
character(len=1024) :: cat_val
1925+
character(len=:), allocatable :: cat_val
19401926

19411927
do_read = .true. ; if (present(do_not_read)) do_read = .not.do_not_read
19421928
do_log = .true. ; if (present(do_not_log)) do_log = .not.do_not_log
@@ -1947,7 +1933,7 @@ subroutine get_param_char_array(CS, modulename, varname, value, desc, units, &
19471933
endif
19481934

19491935
if (do_log) then
1950-
cat_val = trim(value(1)); len_tot = len_trim(value(1))
1936+
cat_val = trim(value(1)) ; len_tot = len_trim(value(1))
19511937
do i=2,size(value)
19521938
len_val = len_trim(value(i))
19531939
if ((len_val > 0) .and. (len_tot + len_val + 2 < 240)) then

0 commit comments

Comments
 (0)