@@ -4,8 +4,100 @@ module test_string_intrinsic
44 use stdlib_string_type
55 implicit none
66
7+ abstract interface
8+ ! > Actual tester working on a string type and a fixed length character
9+ ! > representing the same character sequence
10+ subroutine check1_interface (str1 , chr1 )
11+ import :: string_type
12+ type (string_type), intent (in ) :: str1
13+ character (len=* ), intent (in ) :: chr1
14+ end subroutine check1_interface
15+
16+ ! > Actual tester working on two pairs of string type and fixed length
17+ ! > character representing the same character sequences
18+ subroutine check2_interface (str1 , chr1 , str2 , chr2 )
19+ import :: string_type
20+ type (string_type), intent (in ) :: str1, str2
21+ character (len=* ), intent (in ) :: chr1, chr2
22+ end subroutine check2_interface
23+ end interface
24+
725contains
826
27+ ! > Generate then checker both for the string type created from the character
28+ ! > sequence by the contructor and the assignment operation
29+ subroutine check1 (chr1 , checker )
30+ character (len=* ), intent (in ) :: chr1
31+ procedure (check1_interface) :: checker
32+ call constructor_check1(chr1, checker)
33+ call assignment_check1(chr1, checker)
34+ end subroutine check1
35+
36+ ! > Run the actual checker with a string type generated by the custom constructor
37+ subroutine constructor_check1 (chr1 , checker )
38+ character (len=* ), intent (in ) :: chr1
39+ procedure (check1_interface) :: checker
40+ call checker(string_type(chr1), chr1)
41+ end subroutine constructor_check1
42+
43+ ! > Run the actual checker with a string type generated by assignment
44+ subroutine assignment_check1 (chr1 , checker )
45+ character (len=* ), intent (in ) :: chr1
46+ type (string_type) :: str1
47+ procedure (check1_interface) :: checker
48+ str1 = chr1
49+ call checker(str1, chr1)
50+ end subroutine assignment_check1
51+
52+ ! > Generate then checker both for the string type created from the character
53+ ! > sequence by the contructor and the assignment operation as well as the
54+ ! > mixed assigment and constructor setup
55+ subroutine check2 (chr1 , chr2 , checker )
56+ character (len=* ), intent (in ) :: chr1, chr2
57+ procedure (check2_interface) :: checker
58+ call constructor_check2(chr1, chr2, checker)
59+ call assignment_check2(chr1, chr2, checker)
60+ call mixed_check2(chr1, chr2, checker)
61+ end subroutine check2
62+
63+ ! > Run the actual checker with both string types generated by the custom constructor
64+ subroutine constructor_check2 (chr1 , chr2 , checker )
65+ character (len=* ), intent (in ) :: chr1, chr2
66+ procedure (check2_interface) :: checker
67+ call checker(string_type(chr1), chr1, string_type(chr2), chr2)
68+ end subroutine constructor_check2
69+
70+ ! > Run the actual checker with one string type generated by the custom constructor
71+ ! > and the other by assignment
72+ subroutine mixed_check2 (chr1 , chr2 , checker )
73+ character (len=* ), intent (in ) :: chr1, chr2
74+ type (string_type) :: str1, str2
75+ procedure (check2_interface) :: checker
76+ str1 = chr1
77+ str2 = chr2
78+ call checker(str1, chr1, string_type(chr2), chr2)
79+ call checker(string_type(chr1), chr1, str2, chr2)
80+ end subroutine mixed_check2
81+
82+ ! > Run the actual checker with both string types generated by assignment
83+ subroutine assignment_check2 (chr1 , chr2 , checker )
84+ character (len=* ), intent (in ) :: chr1, chr2
85+ type (string_type) :: str1, str2
86+ procedure (check2_interface) :: checker
87+ str1 = chr1
88+ str2 = chr2
89+ call checker(str1, chr1, str2, chr2)
90+ end subroutine assignment_check2
91+
92+ ! > Generator for checking the lexical comparison
93+ subroutine gen_lgt (str1 , chr1 , str2 , chr2 )
94+ type (string_type), intent (in ) :: str1, str2
95+ character (len=* ), intent (in ) :: chr1, chr2
96+ call check(lgt(str1, str2) .eqv. lgt(chr1, chr2))
97+ call check(lgt(str1, chr2) .eqv. lgt(chr1, chr2))
98+ call check(lgt(chr1, str2) .eqv. lgt(chr1, chr2))
99+ end subroutine gen_lgt
100+
9101 subroutine test_lgt
10102 type (string_type) :: string
11103 logical :: res
@@ -19,8 +111,21 @@ subroutine test_lgt
19111
20112 res = lgt(string, " cde" )
21113 call check(res .eqv. .false. )
114+
115+ call check2(" bcd" , " abc" , gen_lgt)
116+ call check2(" bcd" , " bcd" , gen_lgt)
117+ call check2(" bcd" , " cde" , gen_lgt)
22118 end subroutine test_lgt
23119
120+ ! > Generator for checking the lexical comparison
121+ subroutine gen_llt (str1 , chr1 , str2 , chr2 )
122+ type (string_type), intent (in ) :: str1, str2
123+ character (len=* ), intent (in ) :: chr1, chr2
124+ call check(llt(str1, str2) .eqv. llt(chr1, chr2))
125+ call check(llt(str1, chr2) .eqv. llt(chr1, chr2))
126+ call check(llt(chr1, str2) .eqv. llt(chr1, chr2))
127+ end subroutine gen_llt
128+
24129 subroutine test_llt
25130 type (string_type) :: string
26131 logical :: res
@@ -34,8 +139,21 @@ subroutine test_llt
34139
35140 res = llt(string, " cde" )
36141 call check(res .eqv. .true. )
142+
143+ call check2(" bcd" , " abc" , gen_llt)
144+ call check2(" bcd" , " bcd" , gen_llt)
145+ call check2(" bcd" , " cde" , gen_llt)
37146 end subroutine test_llt
38147
148+ ! > Generator for checking the lexical comparison
149+ subroutine gen_lge (str1 , chr1 , str2 , chr2 )
150+ type (string_type), intent (in ) :: str1, str2
151+ character (len=* ), intent (in ) :: chr1, chr2
152+ call check(lge(str1, str2) .eqv. lge(chr1, chr2))
153+ call check(lge(str1, chr2) .eqv. lge(chr1, chr2))
154+ call check(lge(chr1, str2) .eqv. lge(chr1, chr2))
155+ end subroutine gen_lge
156+
39157 subroutine test_lge
40158 type (string_type) :: string
41159 logical :: res
@@ -49,8 +167,21 @@ subroutine test_lge
49167
50168 res = lge(string, " cde" )
51169 call check(res .eqv. .false. )
170+
171+ call check2(" bcd" , " abc" , gen_lge)
172+ call check2(" bcd" , " bcd" , gen_lge)
173+ call check2(" bcd" , " cde" , gen_lge)
52174 end subroutine test_lge
53175
176+ ! > Generator for checking the lexical comparison
177+ subroutine gen_lle (str1 , chr1 , str2 , chr2 )
178+ type (string_type), intent (in ) :: str1, str2
179+ character (len=* ), intent (in ) :: chr1, chr2
180+ call check(lle(str1, str2) .eqv. lle(chr1, chr2))
181+ call check(lle(str1, chr2) .eqv. lle(chr1, chr2))
182+ call check(lle(chr1, str2) .eqv. lle(chr1, chr2))
183+ end subroutine gen_lle
184+
54185 subroutine test_lle
55186 type (string_type) :: string
56187 logical :: res
@@ -64,16 +195,39 @@ subroutine test_lle
64195
65196 res = lle(string, " cde" )
66197 call check(res .eqv. .true. )
198+
199+ call check2(" bcd" , " abc" , gen_lle)
200+ call check2(" bcd" , " bcd" , gen_lle)
201+ call check2(" bcd" , " cde" , gen_lle)
67202 end subroutine test_lle
68203
204+ ! > Generator for checking the trimming of whitespace
205+ subroutine gen_trim (str1 , chr1 )
206+ type (string_type), intent (in ) :: str1
207+ character (len=* ), intent (in ) :: chr1
208+ call check(len (trim (str1)) == len (trim (chr1)))
209+ end subroutine gen_trim
210+
69211 subroutine test_trim
70212 type (string_type) :: string, trimmed_str
71213
72214 string = " Whitespace "
73215 trimmed_str = trim (string)
74216 call check(len (trimmed_str) == 10 )
217+
218+ call check1(" Whitespace " , gen_trim)
219+ call check1(" W h i t e s p a ce " , gen_trim)
220+ call check1(" SPACE SPACE" , gen_trim)
221+ call check1(" " , gen_trim)
75222 end subroutine test_trim
76223
224+ ! > Generator for checking the length of the character sequence
225+ subroutine gen_len (str1 , chr1 )
226+ type (string_type), intent (in ) :: str1
227+ character (len=* ), intent (in ) :: chr1
228+ call check(len (str1) == len (chr1))
229+ end subroutine gen_len
230+
77231 subroutine test_len
78232 type (string_type) :: string
79233 integer :: length
@@ -85,8 +239,20 @@ subroutine test_len
85239 string = " Whitespace "
86240 length = len (string)
87241 call check(length == 38 )
242+
243+ call check1(" Example string" , gen_len)
244+ call check1(" S P A C E D S T R I N G" , gen_len)
245+ call check1(" With trailing whitespace " , gen_len)
246+ call check1(" centered " , gen_len)
88247 end subroutine test_len
89248
249+ ! > Generator for checking the length of the character sequence without whitespace
250+ subroutine gen_len_trim (str1 , chr1 )
251+ type (string_type), intent (in ) :: str1
252+ character (len=* ), intent (in ) :: chr1
253+ call check(len_trim (str1) == len_trim (chr1))
254+ end subroutine gen_len_trim
255+
90256 subroutine test_len_trim
91257 type (string_type) :: string
92258 integer :: length
@@ -98,24 +264,59 @@ subroutine test_len_trim
98264 string = " Whitespace "
99265 length = len_trim (string)
100266 call check(length == 10 )
267+
268+ call check1(" Example string" , gen_len_trim)
269+ call check1(" S P A C E D S T R I N G" , gen_len_trim)
270+ call check1(" With trailing whitespace " , gen_len_trim)
271+ call check1(" centered " , gen_len_trim)
101272 end subroutine test_len_trim
102273
274+ ! > Generator for checking the left adjustment of the character sequence
275+ subroutine gen_adjustl (str1 , chr1 )
276+ type (string_type), intent (in ) :: str1
277+ character (len=* ), intent (in ) :: chr1
278+ call check(adjustl (str1) == adjustl (chr1))
279+ end subroutine gen_adjustl
280+
103281 subroutine test_adjustl
104282 type (string_type) :: string
105283
106284 string = " Whitespace"
107285 string = adjustl (string)
108286 call check(char (string) == " Whitespace " )
287+
288+ call check1(" B L A N K S " , gen_adjustl)
109289 end subroutine test_adjustl
110290
291+ ! > Generator for checking the right adjustment of the character sequence
292+ subroutine gen_adjustr (str1 , chr1 )
293+ type (string_type), intent (in ) :: str1
294+ character (len=* ), intent (in ) :: chr1
295+ call check(adjustr (str1) == adjustr (chr1))
296+ end subroutine gen_adjustr
297+
111298 subroutine test_adjustr
112299 type (string_type) :: string
113300
114301 string = " Whitespace "
115302 string = adjustr (string)
116303 call check(char (string) == " Whitespace" )
304+
305+ call check1(" B L A N K S " , gen_adjustr)
117306 end subroutine test_adjustr
118307
308+ ! > Generator for checking the presence of a character set in a character sequence
309+ subroutine gen_scan (str1 , chr1 , str2 , chr2 )
310+ type (string_type), intent (in ) :: str1, str2
311+ character (len=* ), intent (in ) :: chr1, chr2
312+ call check(scan (str1, str2) == scan (chr1, chr2))
313+ call check(scan (str1, chr2) == scan (chr1, chr2))
314+ call check(scan (chr1, str2) == scan (chr1, chr2))
315+ call check(scan (str1, str2, back= .true. ) == scan (chr1, chr2, back= .true. ))
316+ call check(scan (str1, chr2, back= .true. ) == scan (chr1, chr2, back= .true. ))
317+ call check(scan (chr1, str2, back= .true. ) == scan (chr1, chr2, back= .true. ))
318+ end subroutine gen_scan
319+
119320 subroutine test_scan
120321 type (string_type) :: string
121322 integer :: pos
@@ -129,8 +330,24 @@ subroutine test_scan
129330
130331 pos = scan (string, " c++" )
131332 call check(pos == 0 )
333+
334+ call check2(" fortran" , " ao" , gen_scan)
335+ call check2(" c++" , " fortran" , gen_scan)
336+
132337 end subroutine test_scan
133338
339+ ! > Generator for checking the absence of a character set in a character sequence
340+ subroutine gen_verify (str1 , chr1 , str2 , chr2 )
341+ type (string_type), intent (in ) :: str1, str2
342+ character (len=* ), intent (in ) :: chr1, chr2
343+ call check(verify (str1, str2) == verify (chr1, chr2))
344+ call check(verify (str1, chr2) == verify (chr1, chr2))
345+ call check(verify (chr1, str2) == verify (chr1, chr2))
346+ call check(verify (str1, str2, back= .true. ) == verify (chr1, chr2, back= .true. ))
347+ call check(verify (str1, chr2, back= .true. ) == verify (chr1, chr2, back= .true. ))
348+ call check(verify (chr1, str2, back= .true. ) == verify (chr1, chr2, back= .true. ))
349+ end subroutine gen_verify
350+
134351 subroutine test_verify
135352 type (string_type) :: string
136353 integer :: pos
@@ -150,16 +367,46 @@ subroutine test_verify
150367
151368 pos = verify (string, string)
152369 call check(pos == 0 )
370+
371+ call check2(" fortran" , " ao" , gen_verify)
372+ call check2(" c++" , " fortran" , gen_verify)
373+
153374 end subroutine test_verify
154375
376+ ! > Generator for the repeatition of a character sequence
377+ subroutine gen_repeat (str1 , chr1 )
378+ type (string_type), intent (in ) :: str1
379+ character (len=* ), intent (in ) :: chr1
380+ integer :: i
381+ do i = 12 , 3 , - 2
382+ call check(repeat (str1, i) == repeat (chr1, i))
383+ end do
384+ end subroutine gen_repeat
385+
155386 subroutine test_repeat
156387 type (string_type) :: string
157388
158389 string = " What? "
159390 string = repeat (string, 3 )
160391 call check(string == " What? What? What? " )
392+
393+ call check1(" !!1!" , gen_repeat)
394+ call check1(" This sentence is repeated multiple times. " , gen_repeat)
395+
161396 end subroutine test_repeat
162397
398+ ! > Generator for checking the substring search in a character string
399+ subroutine gen_index (str1 , chr1 , str2 , chr2 )
400+ type (string_type), intent (in ) :: str1, str2
401+ character (len=* ), intent (in ) :: chr1, chr2
402+ call check(index (str1, str2) == index (chr1, chr2))
403+ call check(index (str1, chr2) == index (chr1, chr2))
404+ call check(index (chr1, str2) == index (chr1, chr2))
405+ call check(index (str1, str2, back= .true. ) == index (chr1, chr2, back= .true. ))
406+ call check(index (str1, chr2, back= .true. ) == index (chr1, chr2, back= .true. ))
407+ call check(index (chr1, str2, back= .true. ) == index (chr1, chr2, back= .true. ))
408+ end subroutine gen_index
409+
163410 subroutine test_index
164411 type (string_type) :: string
165412 integer :: pos
@@ -173,6 +420,10 @@ subroutine test_index
173420
174421 pos = index (string, " This" )
175422 call check(pos == 0 )
423+
424+ call check2(" Search this string for this expression" , " this" , gen_index)
425+ call check2(" Search this string for this expression" , " This" , gen_index)
426+
176427 end subroutine test_index
177428
178429 subroutine test_char
@@ -236,4 +487,3 @@ program tester
236487 call test_iachar
237488
238489end program tester
239-
0 commit comments