FV3 Bundle
ncdw_strarrutils.F90
Go to the documentation of this file.
1 ! utils.f90
2 ! general utilities for Fortran programs
3 ! Author: Albert Huang for SSAI/NASA GSFC GMAO
4 
6  implicit none
7 
8  contains
9  function lentrim(s)
10  character(len=*) :: s
11  integer lentrim
12 
13  do lentrim = len(s), 1, -1
14  if (s(lentrim:lentrim) .ne. ' ') return
15  end do
16  end function lentrim
17 
18  function string_count_substr(s, substr) result(sub_count)
19  character(len=*), intent(in) :: s
20  character(len=*), intent(in) :: substr
21  integer :: sub_count
22 
23  integer :: substr_len, i, jump
24  substr_len = len(substr)
25  sub_count = 0
26  jump = 1
27  i = 1
28 
29  do while (i <= len(s) - len(substr))
30  if (s(i:i+len(substr)-1) == substr) then
31  sub_count = sub_count + 1
32  jump = len(substr)
33  else
34  jump = 1
35  end if
36 
37  i = i + jump
38  end do
39  end function string_count_substr
40 
41  function string_get_max_split(s, substr) result(max_len)
42  character(len=*), intent(in) :: s
43  character(len=*), intent(in) :: substr
44  integer :: sub_count
45 
46  integer :: substr_len, i, jump
47  integer :: max_len, tmp_len
48 
49  substr_len = len(substr)
50  sub_count = 0
51  jump = 1
52  i = 1
53 
54  tmp_len = 0
55  max_len = 0
56 
57  do while (i <= len_trim(s) - len(substr) + 1)
58  if (s(i:i+len(substr)-1) == substr) then
59  sub_count = sub_count + 1
60  if (tmp_len > max_len) max_len = tmp_len
61  tmp_len = 0
62  jump = len(substr)
63  else
64  jump = 1
65  tmp_len = tmp_len + 1
66  end if
67 
68  i = i + jump
69  end do
70 
71  ! Do one more check to ensure we get the end!
72  if ((tmp_len + len(substr) - 1) > max_len) max_len = tmp_len + len(substr) - 1
73  end function string_get_max_split
74 
75  function string_split_index(s, delimiter) result(split_strings)
76  character(len=*) :: s
77  character(len=*) :: delimiter
78 
79  integer :: substr_len, i, jump
80  integer :: tmp_idx, start_idx, total
81  integer :: split_length, item_length
82 
83  character(len=:), allocatable :: split_strings(:)
84  character(len=:), allocatable :: tmp_str
85 
86  ! Get lengths
87  split_length = string_count_substr(s, delimiter) + 1
88  item_length = string_get_max_split(s, delimiter)
89 
90  allocate(character(item_length) :: split_strings(split_length))
91  allocate(character(item_length) :: tmp_str)
92 
93  substr_len = len(delimiter)
94  jump = 1
95  i = 1
96 
97  tmp_idx = 1
98  start_idx = 1
99  total = 1
100 
101  do while (i <= len_trim(s) - len(delimiter) + 1)
102  if (s(i:i+len(delimiter)-1) == delimiter) then
103  if (start_idx /= tmp_idx) then
104  split_strings(total) = s(start_idx:tmp_idx - 1)
105  else
106  split_strings(total) = ""
107  end if
108 
109  tmp_idx = tmp_idx + len(delimiter)
110  start_idx = tmp_idx
111 
112  total = total + 1
113 
114  jump = len(delimiter)
115  else
116  jump = 1
117  tmp_idx = tmp_idx + 1
118  end if
119 
120  i = i + jump
121  end do
122 
123  ! Do one more check to ensure we get the end!
124  split_strings(total) = s(start_idx:tmp_idx - 1)
125  end function string_split_index
126 
127  ! asl = assumed shape length
128  subroutine string_array_dump(strings)
129  character(len=:), allocatable :: strings(:)
130  integer i
131 
132  write (*, "(A, I0)") "Length of strings array: ", size(strings(:))
133  print *, " -> String array dump:"
134 
135  do i = 1, size(strings(:))
136  if (strings(i) == "") then
137  write (*, "(A, I0, A, I0, A, I0, A)") " --> Position ", i, ": (empty) [Trim length = ", len_trim(strings(i)), ", Full length = ", len(strings(i)), "]"
138  else
139  write (*, "(A, I0, A, A, A, I0, A, I0, A)") " --> Position ", i, ": '", trim(strings(i)), "' [Trim length = ", len_trim(strings(i)), ", Full length = ", len(strings(i)), "]"
140  end if
141  end do
142  end subroutine string_array_dump
143 
144  function max_len_string_array(str_arr, arr_length) result(max_len)
145  character(len=*), intent(in) :: str_arr(:)
146  integer , intent(in) :: arr_length
147 
148  integer :: i, max_len
149 
150  max_len = -1
151 
152 #ifdef _DEBUG_MEM_
153  write (*, "(A, I0)") " ** max_len_string_array: size(str_arr) is ", size(str_arr)
154 #endif
155 
156  do i = 1, arr_length
157  if (len_trim(str_arr(i)) > max_len) max_len = len_trim(str_arr(i))
158 #ifdef _DEBUG_MEM_
159  write (*, "(A, I0, A, I0)") "max_len_string_array: str_arr(", i, ") is " // trim(str_arr(i)) // ", size is ", len_trim(str_arr(i))
160  write (*, "(A, I0)") "max_len_string_array: max_len is ", max_len
161 #endif
162  end do
163  end function max_len_string_array
164 
165  function max_len_notrim_string_array(str_arr, arr_length) result(max_len)
166  character(len=*), intent(in) :: str_arr(:)
167  integer , intent(in) :: arr_length
168 
169  integer :: i, max_len
170 
171  max_len = -1
172 
173 #ifdef _DEBUG_MEM_
174  write (*, "(A, I0)") " ** max_len_notrim_string_array: size(str_arr) is ", size(str_arr)
175 #endif
176 
177  do i = 1, arr_length
178  if (len(str_arr(i)) > max_len) max_len = len(str_arr(i))
179 #ifdef _DEBUG_MEM_
180  write (*, "(A, I0, A, I0)") "max_len_notrim_string_array: str_arr(", i, ") is " // trim(str_arr(i)) // ", size is ", len_trim(str_arr(i))
181  write (*, "(A, I0)") "max_len_notrim_string_array: max_len is ", max_len
182 #endif
183  end do
184  end function max_len_notrim_string_array
185 
186  subroutine string_before_delimiter(s, delimiter, string_part)
187  character(len=*), intent(in) :: s
188  character(len=*), intent(in) :: delimiter
189  character(len=:), intent(inout), allocatable :: string_part
190 
191  integer :: substr_len, i, jump
192  integer :: tmp_idx, start_idx, total
193 
194  logical found
195  found = .false.
196 
197  ! Get lengths
198  substr_len = len(delimiter)
199  jump = 1
200  i = 1
201 
202  tmp_idx = 1
203  start_idx = 1
204  total = 1
205 
206  do while (i <= len_trim(s) - len(delimiter) + 1)
207  if (s(i:i+len(delimiter)-1) == delimiter) then
208  found = .true.
209  exit
210  else
211  jump = 1
212  tmp_idx = tmp_idx + 1
213  end if
214 
215  i = i + jump
216  end do
217 
218  ! Do one more check to ensure we get the end!
219  if (found) then
220  if (start_idx == tmp_idx) then
221  allocate(character(0) :: string_part)
222  string_part = ""
223  else
224  allocate(character(tmp_idx - start_idx + 1) :: string_part)
225  string_part = s(start_idx:tmp_idx - 1)
226  end if
227  else
228  allocate(character(len(s)) :: string_part)
229  string_part = s
230  end if
231  end subroutine string_before_delimiter
232 end module ncdw_strarrutils
integer function lentrim(s)
subroutine string_before_delimiter(s, delimiter, string_part)
integer function max_len_string_array(str_arr, arr_length)
integer function string_get_max_split(s, substr)
integer function max_len_notrim_string_array(str_arr, arr_length)
character(len=:) function, dimension(:), allocatable string_split_index(s, delimiter)
subroutine string_array_dump(strings)
integer function string_count_substr(s, substr)