MOM6
mom_string_functions Module Reference

Detailed Description

Handy functions for manipulating strings.

By Alistair Adcroft and Robert Hallberg, last updated Sept. 2013.

The functions here perform a set of useful manipulations of character strings. Although they are a part of MOM6, the do not require any other MOM software to be useful.

Functions/Subroutines

character(len=len(input_string)) function, public lowercase (input_string)
 Return a string in which all uppercase letters have been replaced by their lowercase counterparts. More...
 
character(len=len(input_string)) function, public uppercase (input_string)
 Return a string in which all uppercase letters have been replaced by their lowercase counterparts. More...
 
character(len=19) function, public left_int (i)
 Returns a character string of a left-formatted integer e.g. "123 " (assumes 19 digit maximum) More...
 
character(len=1320) function, public left_ints (i)
 Returns a character string of a comma-separated, compact formatted, integers e.g. "1, 2, 3, 4". More...
 
character(len=32) function, public left_real (val)
 Returns a left-justified string with a real formatted like '(G)'. More...
 
character(len=1320) function, public left_reals (r, sep)
 Returns a character string of a comma-separated, compact formatted, reals e.g. "1., 2., 5*3., 5.E2". More...
 
logical function isformattedfloatequalto (str, val)
 Returns True if the string can be read/parsed to give the exact value of "val". More...
 
character(len=120) function, public extractword (string, n)
 Returns the string corresponding to the nth word in the argument or "" if the string is not long enough. Both spaces and commas are interpreted as separators. More...
 
character(len=120) function, public extract_word (string, separators, n)
 Returns the string corresponding to the nth word in the argument or "" if the string is not long enough. Words are delineated by the mandatory separators argument. More...
 
integer function, public extract_integer (string, separators, n, missing_value)
 Returns the integer corresponding to the nth word in the argument. More...
 
real function, public extract_real (string, separators, n, missing_value)
 Returns the real corresponding to the nth word in the argument. More...
 
character(len=120) function, public remove_spaces (string)
 Returns string with all spaces removed. More...
 
logical function, public string_functions_unit_tests (verbose)
 Returns true if a unit test of string_functions fails. More...
 
logical function localtests (verbose, str1, str2)
 True if str1 does not match str2. False otherwise. More...
 
logical function localtesti (verbose, i1, i2)
 True if i1 is not equal to i2. False otherwise. More...
 
logical function localtestr (verbose, r1, r2)
 True if r1 is not equal to r2. False otherwise. More...
 
character(len=len(dir)+2) function, public slasher (dir)
 Returns a directory name that is terminated with a "/" or "./" if the argument is an empty string. More...
 

Function/Subroutine Documentation

◆ extract_integer()

integer function, public mom_string_functions::extract_integer ( character(len=*), intent(in)  string,
character(len=*), intent(in)  separators,
integer, intent(in)  n,
integer, intent(in), optional  missing_value 
)

Returns the integer corresponding to the nth word in the argument.

Parameters
[in]stringString to scan
[in]separatorsCharacters to use for delineation
[in]nNumber of word to extract
[in]missing_valueValue to assign if word is missing

Definition at line 246 of file MOM_string_functions.F90.

246  character(len=*), intent(in) :: string !< String to scan
247  character(len=*), intent(in) :: separators !< Characters to use for delineation
248  integer, intent(in) :: n !< Number of word to extract
249  integer, optional, intent(in) :: missing_value !< Value to assign if word is missing
250  ! Local variables
251  integer :: ns, i, b, e, nw
252  character(len=20) :: word
253 
254  word = extract_word(string, separators, n)
255 
256  if (len_trim(word)>0) then
257  read(word(1:len_trim(word)),*) extract_integer
258  else
259  if (present(missing_value)) then
260  extract_integer = missing_value
261  else
262  extract_integer = 0
263  endif
264  endif
265 

◆ extract_real()

real function, public mom_string_functions::extract_real ( character(len=*), intent(in)  string,
character(len=*), intent(in)  separators,
integer, intent(in)  n,
real, intent(in), optional  missing_value 
)

Returns the real corresponding to the nth word in the argument.

Parameters
[in]stringString to scan
[in]separatorsCharacters to use for delineation
[in]nNumber of word to extract
[in]missing_valueValue to assign if word is missing

Definition at line 270 of file MOM_string_functions.F90.

270  character(len=*), intent(in) :: string !< String to scan
271  character(len=*), intent(in) :: separators !< Characters to use for delineation
272  integer, intent(in) :: n !< Number of word to extract
273  real, optional, intent(in) :: missing_value !< Value to assign if word is missing
274  ! Local variables
275  integer :: ns, i, b, e, nw
276  character(len=20) :: word
277 
278  word = extract_word(string, separators, n)
279 
280  if (len_trim(word)>0) then
281  read(word(1:len_trim(word)),*) extract_real
282  else
283  if (present(missing_value)) then
284  extract_real = missing_value
285  else
286  extract_real = 0
287  endif
288  endif
289 

◆ extract_word()

character(len=120) function, public mom_string_functions::extract_word ( character(len=*), intent(in)  string,
character(len=*), intent(in)  separators,
integer, intent(in)  n 
)

Returns the string corresponding to the nth word in the argument or "" if the string is not long enough. Words are delineated by the mandatory separators argument.

Parameters
[in]stringString to scan
[in]separatorsCharacters to use for delineation
[in]nNumber of word to extract

Definition at line 209 of file MOM_string_functions.F90.

209  character(len=*), intent(in) :: string !< String to scan
210  character(len=*), intent(in) :: separators !< Characters to use for delineation
211  integer, intent(in) :: n !< Number of word to extract
212  ! Local variables
213  integer :: ns, i, b, e, nw
214  logical :: lastcharisseperator
215  extract_word = ''
216  lastcharisseperator = .true.
217  ns = len_trim(string)
218  i = 0; b=0; e=0; nw=0
219  do while (i<ns)
220  i = i+1
221  if (lastcharisseperator) then ! search for end of word
222  if (verify(string(i:i),separators)==0) then
223  continue ! Multiple separators
224  else
225  lastcharisseperator = .false. ! character is beginning of word
226  b = i
227  continue
228  endif
229  else ! continue search for end of word
230  if (verify(string(i:i),separators)==0) then
231  lastcharisseperator = .true.
232  e = i-1 ! Previous character is end of word
233  nw = nw+1
234  if (nw==n) then
235  extract_word = trim(string(b:e))
236  return
237  endif
238  endif
239  endif
240  enddo
241  if (b<=ns .and. nw==n-1) extract_word = trim(string(b:ns))

◆ extractword()

character(len=120) function, public mom_string_functions::extractword ( character(len=*), intent(in)  string,
integer, intent(in)  n 
)

Returns the string corresponding to the nth word in the argument or "" if the string is not long enough. Both spaces and commas are interpreted as separators.

Parameters
[in]stringThe string to scan
[in]nNumber of word to extract

Definition at line 198 of file MOM_string_functions.F90.

198  character(len=*), intent(in) :: string !< The string to scan
199  integer, intent(in) :: n !< Number of word to extract
200 
201  extractword = extract_word(string, ' ,', n)
202 

◆ isformattedfloatequalto()

logical function mom_string_functions::isformattedfloatequalto ( character(len=*), intent(in)  str,
real, intent(in)  val 
)
private

Returns True if the string can be read/parsed to give the exact value of "val".

Parameters
[in]strThe string to parse
[in]valThe real value to compare with

Definition at line 182 of file MOM_string_functions.F90.

182  character(len=*), intent(in) :: str !< The string to parse
183  real, intent(in) :: val !< The real value to compare with
184  logical :: isformattedfloatequalto
185  ! Local variables
186  real :: scannedval
187 
188  isformattedfloatequalto=.false.
189  read(str(1:),*,err=987) scannedval
190  if (scannedval == val) isformattedfloatequalto=.true.
191  987 return

◆ left_int()

character(len=19) function, public mom_string_functions::left_int ( integer, intent(in)  i)

Returns a character string of a left-formatted integer e.g. "123 " (assumes 19 digit maximum)

Parameters
[in]iThe integer to convert to a string
Returns
The output string

Definition at line 62 of file MOM_string_functions.F90.

62  integer, intent(in) :: i !< The integer to convert to a string
63  character(len=19) :: left_int !< The output string
64 
65  character(len=19) :: tmp
66  write(tmp(1:19),'(I19)') i
67  write(left_int(1:19),'(A)') adjustl(tmp)

◆ left_ints()

character(len=1320) function, public mom_string_functions::left_ints ( integer, dimension(:), intent(in)  i)

Returns a character string of a comma-separated, compact formatted, integers e.g. "1, 2, 3, 4".

Parameters
[in]iThe array of integers to convert to a string
Returns
The output string

Definition at line 73 of file MOM_string_functions.F90.

73  integer, intent(in) :: i(:) !< The array of integers to convert to a string
74  character(len=1320) :: left_ints !< The output string
75 
76  character(len=1320) :: tmp
77  integer :: j
78  write(left_ints(1:1320),'(A)') trim(left_int(i(1)))
79  if (size(i)>1) then
80  do j=2,size(i)
81  tmp=left_ints
82  write(left_ints(1:1320),'(A,", ",A)') trim(tmp),trim(left_int(i(j)))
83  enddo
84  endif

◆ left_real()

character(len=32) function, public mom_string_functions::left_real ( real, intent(in)  val)

Returns a left-justified string with a real formatted like '(G)'.

Parameters
[in]valThe real variable to convert to a string
Returns
The output string

Definition at line 89 of file MOM_string_functions.F90.

89  real, intent(in) :: val !< The real variable to convert to a string
90  character(len=32) :: left_real !< The output string
91 
92  integer :: l, ind
93 
94  if ((abs(val) < 1.0e4) .and. (abs(val) >= 1.0e-3)) then
95  write(left_real, '(F30.11)') val
96  if (.not.isformattedfloatequalto(left_real,val)) then
97  write(left_real, '(F30.12)') val
98  if (.not.isformattedfloatequalto(left_real,val)) then
99  write(left_real, '(F30.13)') val
100  if (.not.isformattedfloatequalto(left_real,val)) then
101  write(left_real, '(F30.14)') val
102  if (.not.isformattedfloatequalto(left_real,val)) then
103  write(left_real, '(F30.15)') val
104  if (.not.isformattedfloatequalto(left_real,val)) then
105  write(left_real, '(F30.16)') val
106  endif
107  endif
108  endif
109  endif
110  endif
111  do
112  l = len_trim(left_real)
113  if ((l<2) .or. (left_real(l-1:l) == ".0") .or. &
114  (left_real(l:l) /= "0")) exit
115  left_real(l:l) = " "
116  enddo
117  elseif (val == 0.) then
118  left_real = "0.0"
119  else
120  if ((abs(val) <= 1.0e-100) .or. (abs(val) >= 1.0e100)) then
121  write(left_real(1:32), '(ES24.14E3)') val
122  if (.not.isformattedfloatequalto(left_real,val)) &
123  write(left_real(1:32), '(ES24.15E3)') val
124  else
125  write(left_real(1:32), '(ES23.14)') val
126  if (.not.isformattedfloatequalto(left_real,val)) &
127  write(left_real(1:32), '(ES23.15)') val
128  endif
129  do
130  ind = index(left_real,"0E")
131  if (ind == 0) exit
132  if (left_real(ind-1:ind-1) == ".") exit
133  left_real = left_real(1:ind-1)//left_real(ind+1:)
134  enddo
135  endif
136  left_real = adjustl(left_real)

◆ left_reals()

character(len=1320) function, public mom_string_functions::left_reals ( real, dimension(:), intent(in)  r,
character(len=*), intent(in), optional  sep 
)

Returns a character string of a comma-separated, compact formatted, reals e.g. "1., 2., 5*3., 5.E2".

Parameters
[in]rThe array of real variables to convert to a string
[in]sepThe separator between successive values, by default it is ', '.
Returns
The output string

Definition at line 142 of file MOM_string_functions.F90.

142  real, intent(in) :: r(:) !< The array of real variables to convert to a string
143  character(len=*), optional, intent(in) :: sep !< The separator between
144  !! successive values, by default it is ', '.
145  character(len=1320) :: left_reals !< The output string
146 
147  integer :: j, n, b, ns
148  logical :: dowrite
149  character(len=10) :: separator
150 
151  n=1 ; dowrite=.true. ; left_reals='' ; b=1
152  if (present(sep)) then
153  separator=sep ; ns=len(sep)
154  else
155  separator=', ' ; ns=2
156  endif
157  do j=1,size(r)
158  dowrite=.true.
159  if (j<size(r)) then
160  if (r(j)==r(j+1)) then
161  n=n+1
162  dowrite=.false.
163  endif
164  endif
165  if (dowrite) then
166  if (b>1) then ! Write separator if a number has already been written
167  write(left_reals(b:),'(A)') separator
168  b=b+ns
169  endif
170  if (n>1) then
171  write(left_reals(b:),'(A,"*",A)') trim(left_int(n)),trim(left_real(r(j)))
172  else
173  write(left_reals(b:),'(A)') trim(left_real(r(j)))
174  endif
175  n=1 ; b=len_trim(left_reals)+1
176  endif
177  enddo

◆ localtesti()

logical function mom_string_functions::localtesti ( logical, intent(in)  verbose,
integer, intent(in)  i1,
integer, intent(in)  i2 
)
private

True if i1 is not equal to i2. False otherwise.

Parameters
[in]verboseIf true, write results to stdout
[in]i1Integer
[in]i2Integer

Definition at line 376 of file MOM_string_functions.F90.

376  logical, intent(in) :: verbose !< If true, write results to stdout
377  integer, intent(in) :: i1 !< Integer
378  integer, intent(in) :: i2 !< Integer
379  localtesti=.false.
380  if (i1/=i2) localtesti=.true.
381  if (localtesti .or. verbose) then
382  write(stdout,*) i1,i2
383  if (localtesti) then
384  write(stdout,*) i1,'!=',i2, '<-- FAIL'
385  write(stderr,*) i1,'!=',i2, '<-- FAIL'
386  endif
387  endif

◆ localtestr()

logical function mom_string_functions::localtestr ( logical, intent(in)  verbose,
real, intent(in)  r1,
real, intent(in)  r2 
)
private

True if r1 is not equal to r2. False otherwise.

Parameters
[in]verboseIf true, write results to stdout
[in]r1Float
[in]r2Float

Definition at line 392 of file MOM_string_functions.F90.

392  logical, intent(in) :: verbose !< If true, write results to stdout
393  real, intent(in) :: r1 !< Float
394  real, intent(in) :: r2 !< Float
395  localtestr=.false.
396  if (r1/=r2) localtestr=.true.
397  if (localtestr .or. verbose) then
398  write(stdout,*) r1,r2
399  if (localtestr) then
400  write(stdout,*) r1,'!=',r2, '<-- FAIL'
401  write(stderr,*) r1,'!=',r2, '<-- FAIL'
402  endif
403  endif

◆ localtests()

logical function mom_string_functions::localtests ( logical, intent(in)  verbose,
character(len=*), intent(in)  str1,
character(len=*), intent(in)  str2 
)
private

True if str1 does not match str2. False otherwise.

Parameters
[in]verboseIf true, write results to stdout
[in]str1String
[in]str2String

Definition at line 360 of file MOM_string_functions.F90.

360  logical, intent(in) :: verbose !< If true, write results to stdout
361  character(len=*), intent(in) :: str1 !< String
362  character(len=*), intent(in) :: str2 !< String
363  localtests=.false.
364  if (trim(str1)/=trim(str2)) localtests=.true.
365  if (localtests .or. verbose) then
366  write(stdout,*) '>'//trim(str1)//'<'
367  if (localtests) then
368  write(stdout,*) trim(str1),':',trim(str2), '<-- FAIL'
369  write(stderr,*) trim(str1),':',trim(str2), '<-- FAIL'
370  endif
371  endif

◆ lowercase()

character(len=len(input_string)) function, public mom_string_functions::lowercase ( character(len=*), intent(in)  input_string)

Return a string in which all uppercase letters have been replaced by their lowercase counterparts.

Parameters
[in]input_stringThe string to modify
Returns
The modified output string

Definition at line 26 of file MOM_string_functions.F90.

26  character(len=*), intent(in) :: input_string !< The string to modify
27  character(len=len(input_string)) :: lowercase !< The modified output string
28 ! This function returns a string in which all uppercase letters have been
29 ! replaced by their lowercase counterparts. It is loosely based on the
30 ! lowercase function in mpp_util.F90.
31  integer, parameter :: co=iachar('a')-iachar('A') ! case offset
32  integer :: k
33 
34  lowercase = input_string
35  do k=1, len_trim(input_string)
36  if (lowercase(k:k) >= 'A' .and. lowercase(k:k) <= 'Z') &
37  lowercase(k:k) = achar(ichar(lowercase(k:k))+co)
38  enddo

◆ remove_spaces()

character(len=120) function, public mom_string_functions::remove_spaces ( character(len=*), intent(in)  string)

Returns string with all spaces removed.

Parameters
[in]stringString to scan

Definition at line 294 of file MOM_string_functions.F90.

294  character(len=*), intent(in) :: string !< String to scan
295  ! Local variables
296  integer :: ns, i, o
297  logical :: lastcharisseperator
298  lastcharisseperator = .true.
299  ns = len_trim(string)
300  i = 0; o = 0
301  do while (i<ns)
302  i = i+1
303  if (string(i:i) /= ' ') then ! Copy character to output string
304  o = o + 1
305  remove_spaces(o:o) = string(i:i)
306  endif
307  enddo
308  do i = o+1, 120
309  remove_spaces(i:i) = ' ' ! Wipe any non-empty characters
310  enddo
311  remove_spaces = trim(remove_spaces)

◆ slasher()

character(len=len(dir)+2) function, public mom_string_functions::slasher ( character(len=*), intent(in)  dir)

Returns a directory name that is terminated with a "/" or "./" if the argument is an empty string.

Parameters
[in]dirA directory to be terminated with a "/" or changed to "./" if it is blank.

Definition at line 409 of file MOM_string_functions.F90.

409  character(len=*), intent(in) :: dir !< A directory to be terminated with a "/"
410  !! or changed to "./" if it is blank.
411  character(len=len(dir)+2) :: slasher
412 
413  if (len_trim(dir) == 0) then
414  slasher = "./"
415  elseif (dir(len_trim(dir):len_trim(dir)) == '/') then
416  slasher = trim(dir)
417  else
418  slasher = trim(dir)//"/"
419  endif

◆ string_functions_unit_tests()

logical function, public mom_string_functions::string_functions_unit_tests ( logical, intent(in)  verbose)

Returns true if a unit test of string_functions fails.

Parameters
[in]verboseIf true, write results to stdout

Definition at line 316 of file MOM_string_functions.F90.

316  ! Arguments
317  logical, intent(in) :: verbose !< If true, write results to stdout
318  ! Local variables
319  integer :: i(5) = (/ -1, 1, 3, 3, 0 /)
320  real :: r(8) = (/ 0., 1., -2., 1.3, 3.e-11, 3.e-11, 3.e-11, -5.1e12 /)
321  logical :: fail, v
322  fail = .false.
323  v = verbose
324  write(stdout,*) '==== MOM_string_functions: string_functions_unit_tests ==='
325  fail = fail .or. localtests(v,left_int(-1),'-1')
326  fail = fail .or. localtests(v,left_ints(i(:)),'-1, 1, 3, 3, 0')
327  fail = fail .or. localtests(v,left_real(0.),'0.0')
328  fail = fail .or. localtests(v,left_reals(r(:)),'0.0, 1.0, -2.0, 1.3, 3*3.0E-11, -5.1E+12')
329  fail = fail .or. localtests(v,left_reals(r(:),sep=' '),'0.0 1.0 -2.0 1.3 3*3.0E-11 -5.1E+12')
330  fail = fail .or. localtests(v,left_reals(r(:),sep=','),'0.0,1.0,-2.0,1.3,3*3.0E-11,-5.1E+12')
331  fail = fail .or. localtests(v,extractword("One Two,Three",1),"One")
332  fail = fail .or. localtests(v,extractword("One Two,Three",2),"Two")
333  fail = fail .or. localtests(v,extractword("One Two,Three",3),"Three")
334  fail = fail .or. localtests(v,extractword("One Two, Three",3),"Three")
335  fail = fail .or. localtests(v,extractword(" One Two,Three",1),"One")
336  fail = fail .or. localtests(v,extract_word("One,Two,Three",",",3),"Three")
337  fail = fail .or. localtests(v,extract_word("One,Two,Three",",",4),"")
338  fail = fail .or. localtests(v,remove_spaces("1 2 3"),"123")
339  fail = fail .or. localtests(v,remove_spaces(" 1 2 3"),"123")
340  fail = fail .or. localtests(v,remove_spaces("1 2 3 "),"123")
341  fail = fail .or. localtests(v,remove_spaces("123"),"123")
342  fail = fail .or. localtests(v,remove_spaces(" "),"")
343  fail = fail .or. localtests(v,remove_spaces(""),"")
344  fail = fail .or. localtesti(v,extract_integer("1","",1),1)
345  fail = fail .or. localtesti(v,extract_integer("1,2,3",",",1),1)
346  fail = fail .or. localtesti(v,extract_integer("1,2",",",2),2)
347  fail = fail .or. localtesti(v,extract_integer("1,2",",",3),0)
348  fail = fail .or. localtesti(v,extract_integer("1,2",",",4,4),4)
349  fail = fail .or. localtestr(v,extract_real("1.","",1),1.)
350  fail = fail .or. localtestr(v,extract_real("1.,2.,3.",",",1),1.)
351  fail = fail .or. localtestr(v,extract_real("1.,2.",",",2),2.)
352  fail = fail .or. localtestr(v,extract_real("1.,2.",",",3),0.)
353  fail = fail .or. localtestr(v,extract_real("1.,2.",",",4,4.),4.)
354  if (.not. fail) write(stdout,*) 'Pass'
355  string_functions_unit_tests = fail

◆ uppercase()

character(len=len(input_string)) function, public mom_string_functions::uppercase ( character(len=*), intent(in)  input_string)

Return a string in which all uppercase letters have been replaced by their lowercase counterparts.

Parameters
[in]input_stringThe string to modify
Returns
The modified output string

Definition at line 44 of file MOM_string_functions.F90.

44  character(len=*), intent(in) :: input_string !< The string to modify
45  character(len=len(input_string)) :: uppercase !< The modified output string
46 ! This function returns a string in which all lowercase letters have been
47 ! replaced by their uppercase counterparts. It is loosely based on the
48 ! uppercase function in mpp_util.F90.
49  integer, parameter :: co=iachar('A')-iachar('a') ! case offset
50  integer :: k
51 
52  uppercase = input_string
53  do k=1, len_trim(input_string)
54  if (uppercase(k:k) >= 'a' .and. uppercase(k:k) <= 'z') &
55  uppercase(k:k) = achar(ichar(uppercase(k:k))+co)
56  enddo