3
! Written by J.L.Schonfelder
4
! Incorporating suggestions by members of the committee ISO/IEC JTC1/SC22/WG5
6
! Version produced (3-Nov-1998)
7
! Updated to exploit facilities included in Fortran 95
9
!-----------------------------------------------------------------------------!
10
! This module defines the interface and one possible implementation for a !
11
! dynamic length character string facility in Fortran 95. The Fortran 95 !
12
! language is defined by the standard ISO/IEC 1539-1 : 1997. !
13
! The publicly accessible interface defined by this module is conformant !
14
! with the auxilliary standard, ISO/IEC 1539-2 : 1999. !
15
! The detailed implementation may be considered as an informal definition of !
16
! the required semantics, and may also be used as a guide to the production !
17
! of a portable implementation. !
18
! N.B. Although every care has been taken to produce valid Fortran code in !
19
! construction of this module no guarantee is given or implied that this !
20
! code will work correctly without error on any specific processor, nor !
21
! is this implementation intended to be in any way optimal either in use !
22
! of storage or CPU cycles. !
23
!-----------------------------------------------------------------------------!
27
!-----------------------------------------------------------------------------!
28
! By default all entities declared or defined in this module are private to !
29
! the module. Only those entities declared explicitly as being public are !
30
! accessible to programs using the module. In particular, the procedures and !
31
! operators defined herein are made accessible via their generic identifiers !
32
! only; their specific names are private. !
33
!-----------------------------------------------------------------------------!
37
CHARACTER,DIMENSION(:),POINTER :: chars => NULL()
40
!-----------------------------------------------------------------------------!
41
! The representation chosen for this definition of the module is of a string !
42
! type consisting of a single component that is a pointer to a rank one array !
44
! Note: this Module is defined only for characters of default kind. A similar !
45
! module could be defined for non-default characters if these are supported !
46
! on a processor by adding a KIND parameter to the component in the type !
47
! definition, and to all delarations of objects of CHARACTER type. !
48
!-----------------------------------------------------------------------------!
50
CHARACTER,PARAMETER :: blank = " "
52
!----- GENERIC PROCEDURE INTERFACE DEFINITIONS -------------------------------!
54
!----- LEN interface ---------------------------------------------------------!
56
MODULE PROCEDURE len_s ! length of string
59
!----- Conversion procedure interfaces ---------------------------------------!
61
MODULE PROCEDURE c_to_s ! character to string
65
MODULE PROCEDURE s_to_c, & ! string to character
66
s_to_fix_c ! string to specified length character
69
!----- ASSIGNMENT interfaces -------------------------------------------------!
70
INTERFACE ASSIGNMENT(=)
71
MODULE PROCEDURE s_ass_s, & ! string = string
72
c_ass_s, & ! character = string
73
s_ass_c ! string = character
76
!----- Concatenation operator interfaces -------------------------------------!
77
INTERFACE OPERATOR(//)
78
MODULE PROCEDURE s_concat_s, & ! string//string
79
s_concat_c, & ! string//character
80
c_concat_s ! character//string
83
!----- Repeated Concatenation interface --------------------------------------!
85
MODULE PROCEDURE repeat_s
88
!------ Equality comparison operator interfaces-------------------------------!
89
INTERFACE OPERATOR(==)
90
MODULE PROCEDURE s_eq_s, & ! string==string
91
s_eq_c, & ! string==character
92
c_eq_s ! character==string
95
!----- not-equality comparison operator interfaces ---------------------------!
96
INTERFACE OPERATOR(/=)
97
MODULE PROCEDURE s_ne_s, & ! string/=string
98
s_ne_c, & ! string/=character
99
c_ne_s ! character/=string
102
!----- less-than comparison operator interfaces ------------------------------!
103
INTERFACE OPERATOR(<)
104
MODULE PROCEDURE s_lt_s, & ! string<string
105
s_lt_c, & ! string<character
106
c_lt_s ! character<string
109
!----- less-than-or-equal comparison operator interfaces ---------------------!
110
INTERFACE OPERATOR(<=)
111
MODULE PROCEDURE s_le_s, & ! string<=string
112
s_le_c, & ! string<=character
113
c_le_s ! character<=string
116
!----- greater-than-or-equal comparison operator interfaces ------------------!
117
INTERFACE OPERATOR(>=)
118
MODULE PROCEDURE s_ge_s, & ! string>=string
119
s_ge_c, & ! string>=character
120
c_ge_s ! character>=string
123
!----- greater-than comparison operator interfaces ---------------------------!
124
INTERFACE OPERATOR(>)
125
MODULE PROCEDURE s_gt_s, & ! string>string
126
s_gt_c, & ! string>character
127
c_gt_s ! character>string
130
!----- LLT procedure interfaces ----------------------------------------------!
132
MODULE PROCEDURE s_llt_s, & ! LLT(string,string)
133
s_llt_c, & ! LLT(string,character)
134
c_llt_s ! LLT(character,string)
137
!----- LLE procedure interfaces ----------------------------------------------!
139
MODULE PROCEDURE s_lle_s, & ! LLE(string,string)
140
s_lle_c, & ! LLE(string,character)
141
c_lle_s ! LLE(character,string)
144
!----- LGE procedure interfaces ----------------------------------------------!
146
MODULE PROCEDURE s_lge_s, & ! LGE(string,string)
147
s_lge_c, & ! LGE(string,character)
148
c_lge_s ! LGE(character,string)
151
!----- LGT procedure interfaces ----------------------------------------------!
153
MODULE PROCEDURE s_lgt_s, & ! LGT(string,string)
154
s_lgt_c, & ! LGT(string,character)
155
c_lgt_s ! LGT(character,string)
158
!----- Input procedure interfaces --------------------------------------------!
160
MODULE PROCEDURE get_d_eor, & ! default unit, EoR termination
161
get_u_eor, & ! specified unit, EoR termination
162
get_d_tset_s, & ! default unit, string set termination
163
get_u_tset_s, & ! specified unit, string set termination
164
get_d_tset_c, & ! default unit, char set termination
165
get_u_tset_c ! specified unit, char set termination
168
!----- Output procedure interfaces -------------------------------------------!
170
MODULE PROCEDURE put_d_s, & ! string to default unit
171
put_u_s, & ! string to specified unit
172
put_d_c, & ! char to default unit
173
put_u_c ! char to specified unit
177
MODULE PROCEDURE putline_d_s, & ! string to default unit
178
putline_u_s, & ! string to specified unit
179
putline_d_c, & ! char to default unit
180
putline_u_c ! char to specified unit
183
!----- Insert procedure interfaces -------------------------------------------!
185
MODULE PROCEDURE insert_ss, & ! string in string
186
insert_sc, & ! char in string
187
insert_cs, & ! string in char
188
insert_cc ! char in char
191
!----- Replace procedure interfaces ------------------------------------------!
193
MODULE PROCEDURE replace_ss, & ! string by string, at specified
194
replace_sc, & ! string by char , starting
195
replace_cs, & ! char by string , point
196
replace_cc, & ! char by char
197
replace_ss_sf,& ! string by string, between
198
replace_sc_sf,& ! string by char , specified
199
replace_cs_sf,& ! char by string , starting and
200
replace_cc_sf,& ! char by char , finishing points
201
replace_sss, & ! in string replace string by string
202
replace_ssc, & ! in string replace string by char
203
replace_scs, & ! in string replace char by string
204
replace_scc, & ! in string replace char by char
205
replace_css, & ! in char replace string by string
206
replace_csc, & ! in char replace string by char
207
replace_ccs, & ! in char replace char by string
208
replace_ccc ! in char replace char by char
211
!----- Remove procedure interface --------------------------------------------!
213
! MODULE PROCEDURE remove_s, & ! characters from string, between start
214
! remove_c ! characters from char , and finish
217
!----- Extract procedure interface -------------------------------------------!
219
MODULE PROCEDURE extract_s, & ! from string extract string, between start
220
extract_c ! from char extract string, and finish
223
!----- Split procedure interface ---------------------------------------------!
225
MODULE PROCEDURE split_s, & ! split string at first occurance of
226
split_c ! character in set
229
!----- Index procedure interfaces --------------------------------------------!
231
MODULE PROCEDURE index_ss, index_sc, index_cs
234
!----- Scan procedure interfaces ---------------------------------------------!
236
MODULE PROCEDURE scan_ss, scan_sc, scan_cs
239
!----- Verify procedure interfaces -------------------------------------------!
241
MODULE PROCEDURE verify_ss, verify_sc, verify_cs
244
!----- Interfaces for remaining intrinsic function overloads -----------------!
246
MODULE PROCEDURE len_trim_s
250
MODULE PROCEDURE trim_s
254
MODULE PROCEDURE iachar_s
258
MODULE PROCEDURE ichar_s
262
MODULE PROCEDURE adjustl_s
266
MODULE PROCEDURE adjustr_s
269
!----- specification of publically accessible entities -----------------------!
270
PUBLIC :: VAR_STR,VARSTR,CHAR,LEN,GET,PUT,PUT_LINE,INSERT,REPLACE, &
271
SPLIT,REPEAT,EXTRACT,INDEX,SCAN,VERIFY,LLT,LLE,LGE,LGT, &
272
ASSIGNMENT(=),OPERATOR(//),OPERATOR(==),OPERATOR(/=),OPERATOR(<), &
273
OPERATOR(<=),OPERATOR(>=),OPERATOR(>),LEN_TRIM,TRIM,IACHAR,ICHAR, &
280
!----- LEN Procedure ---------------------------------------------------------!
281
ELEMENTAL FUNCTION len_s(string) ! generic LEN
282
type(VAR_STR),INTENT(IN) :: string
284
! returns the length of the string argument or zero if there is no current
286
IF(.NOT.ASSOCIATED(string%chars))THEN
289
len_s = SIZE(string%chars)
293
!----- Conversion Procedures ------------------------------------------------!
294
ELEMENTAL FUNCTION c_to_s(chr) ! generic VAR_STR
295
type(VAR_STR) :: c_to_s
296
CHARACTER(LEN=*),INTENT(IN) :: chr
297
! returns the string consisting of the characters char
300
ALLOCATE(c_to_s%chars(1:lc))
302
c_to_s%chars(i) = chr(i:i)
306
PURE FUNCTION s_to_c(string) ! generic CHAR
307
type(VAR_STR),INTENT(IN) :: string
308
CHARACTER(LEN=SIZE(string%chars)) :: s_to_c
309
! returns the characters of string as an automatically sized character
311
lc=SIZE(string%chars)
313
s_to_c(i:i) = string%chars(i)
317
PURE FUNCTION s_to_fix_c(string,length) ! generic CHAR
318
type(VAR_STR),INTENT(IN) :: string
319
INTEGER,INTENT(IN) :: length
320
CHARACTER(LEN=length) :: s_to_fix_c
321
! returns the character of fixed length, length, containing the characters
322
! of string either padded with blanks or truncated on the right to fit
324
lc=MIN(SIZE(string%chars),length)
326
s_to_fix_c(i:i) = string%chars(i)
328
IF(lc < length)THEN ! result longer than string padding needed
329
s_to_fix_c(lc+1:length) = blank
331
ENDFUNCTION s_to_fix_c
333
!----- ASSIGNMENT Procedures -------------------------------------------------!
334
ELEMENTAL SUBROUTINE s_ass_s(var,expr)
335
type(VAR_STR),INTENT(INOUT) :: var
336
type(VAR_STR),INTENT(IN) :: expr
337
! assign a string value to a string variable overriding default assignement
338
! reallocates string variable to size of string value and copies characters
339
if(LEN(expr) == 0)THEN
343
IF(ASSOCIATED(var%chars,expr%chars))THEN
344
CONTINUE ! identity assignment do nothing
345
ELSEIF(ASSOCIATED(var%chars))THEN
346
DEALLOCATE(var%chars)
347
ALLOCATE(var%chars(1:SIZE(expr%chars)))
348
var%chars = expr%chars
350
ALLOCATE(var%chars(1:SIZE(expr%chars)))
351
var%chars = expr%chars
353
ENDSUBROUTINE s_ass_s
355
ELEMENTAL SUBROUTINE c_ass_s(var,expr)
356
CHARACTER(LEN=*),INTENT(OUT) :: var
357
type(VAR_STR),INTENT(IN) :: expr
358
! assign a string value to a character variable
359
! if the string is longer than the character truncate the string on the right
360
! if the string is shorter the character is blank padded on the right
362
lc = LEN(var); ls = MIN(LEN(expr),lc)
364
var(i:i) = expr%chars(i)
369
ENDSUBROUTINE c_ass_s
371
ELEMENTAL SUBROUTINE s_ass_c(var,expr)
372
type(VAR_STR),INTENT(INOUT) :: var
373
CHARACTER(LEN=*),INTENT(IN) :: expr
374
! assign a character value to a string variable
375
! disassociates the string variable from its current value, allocates new
376
! space to hold the characters and copies them from the character value
380
IF(ASSOCIATED(var%chars))DEALLOCATE(var%chars)
382
ALLOCATE(var%chars(1:lc))
384
var%chars(i) = expr(i:i)
386
ENDSUBROUTINE s_ass_c
388
!----- Concatenation operator procedures ------------------------------------!
389
ELEMENTAL FUNCTION s_concat_s(string_a,string_b) ! string//string
390
type(VAR_STR),INTENT(IN) :: string_a,string_b
391
type(VAR_STR) :: s_concat_s
393
la = LEN(string_a); lb = LEN(string_b)
394
ALLOCATE(s_concat_s%chars(1:la+lb))
395
s_concat_s%chars(1:la) = string_a%chars
396
s_concat_s%chars(1+la:la+lb) = string_b%chars
397
ENDFUNCTION s_concat_s
399
ELEMENTAL FUNCTION s_concat_c(string_a,string_b) ! string//character
400
type(VAR_STR),INTENT(IN) :: string_a
401
CHARACTER(LEN=*),INTENT(IN) :: string_b
402
type(VAR_STR) :: s_concat_c
404
la = LEN(string_a); lb = LEN(string_b)
405
ALLOCATE(s_concat_c%chars(1:la+lb))
406
s_concat_c%chars(1:la) = string_a%chars
408
s_concat_c%chars(la+i) = string_b(i:i)
410
ENDFUNCTION s_concat_c
412
ELEMENTAL FUNCTION c_concat_s(string_a,string_b) ! character//string
413
CHARACTER(LEN=*),INTENT(IN) :: string_a
414
type(VAR_STR),INTENT(IN) :: string_b
415
type(VAR_STR) :: c_concat_s
417
la = LEN(string_a); lb = LEN(string_b)
418
ALLOCATE(c_concat_s%chars(1:la+lb))
420
c_concat_s%chars(i) = string_a(i:i)
422
c_concat_s%chars(1+la:la+lb) = string_b%chars
423
ENDFUNCTION c_concat_s
425
!----- Reapeated concatenation procedures -----------------------------------!
426
ELEMENTAL FUNCTION repeat_s(string,ncopies)
427
type(VAR_STR),INTENT(IN) :: string
428
INTEGER,INTENT(IN) :: ncopies
429
type(VAR_STR) :: repeat_s
430
! Returns a string produced by the concatenation of ncopies of the
433
IF (ncopies <= 0) THEN
434
ALLOCATE(repeat_s%chars(1:0)) ! return a zero length string
437
ls = LEN(string); lr = ls*ncopies
438
ALLOCATE(repeat_s%chars(1:lr))
440
repeat_s%chars(1+(i-1)*ls:i*ls) = string%chars
444
!------ Equality comparison operators ----------------------------------------!
445
ELEMENTAL FUNCTION s_eq_s(string_a,string_b) ! string==string
446
type(VAR_STR),INTENT(IN) :: string_a,string_b
449
la = LEN(string_a); lb = LEN(string_b)
451
s_eq_s = ALL(string_a%chars(1:lb) == string_b%chars) .AND. &
452
ALL(string_a%chars(lb+1:la) == blank)
453
ELSEIF (la < lb) THEN
454
s_eq_s = ALL(string_a%chars == string_b%chars(1:la)) .AND. &
455
ALL(blank == string_b%chars(la+1:lb))
457
s_eq_s = ALL(string_a%chars == string_b%chars)
461
ELEMENTAL FUNCTION s_eq_c(string_a,string_b) ! string==character
462
type(VAR_STR),INTENT(IN) :: string_a
463
CHARACTER(LEN=*),INTENT(IN) :: string_b
466
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
468
IF( string_a%chars(i) /= string_b(i:i) )THEN
469
s_eq_c = .FALSE.; RETURN
472
IF( la > lb .AND. ANY( string_a%chars(lb+1:la) /= blank ) )THEN
473
s_eq_c = .FALSE.; RETURN
474
ELSEIF( la < lb .AND. blank /= string_b(la+1:lb) )THEN
475
s_eq_c = .FALSE.; RETURN
480
ELEMENTAL FUNCTION c_eq_s(string_a,string_b) ! character==string
481
CHARACTER(LEN=*),INTENT(IN) :: string_a
482
type(VAR_STR),INTENT(IN) :: string_b
485
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
487
IF( string_a(i:i) /= string_b%chars(i) )THEN
488
c_eq_s = .FALSE.; RETURN
491
IF( la > lb .AND. string_a(lb+1:la) /= blank )THEN
492
c_eq_s = .FALSE.; RETURN
493
ELSEIF( la < lb .AND. ANY( blank /= string_b%chars(la+1:lb) ) )THEN
494
c_eq_s = .FALSE.; RETURN
499
!------ Non-equality operators -----------------------------------------------!
500
ELEMENTAL FUNCTION s_ne_s(string_a,string_b) ! string/=string
501
type(VAR_STR),INTENT(IN) :: string_a,string_b
504
la = LEN(string_a); lb = LEN(string_b)
506
s_ne_s = ANY(string_a%chars(1:lb) /= string_b%chars) .OR. &
507
ANY(string_a%chars(lb+1:la) /= blank)
508
ELSEIF (la < lb) THEN
509
s_ne_s = ANY(string_a%chars /= string_b%chars(1:la)) .OR. &
510
ANY(blank /= string_b%chars(la+1:lb))
512
s_ne_s = ANY(string_a%chars /= string_b%chars)
516
ELEMENTAL FUNCTION s_ne_c(string_a,string_b) ! string/=character
517
type(VAR_STR),INTENT(IN) :: string_a
518
CHARACTER(LEN=*),INTENT(IN) :: string_b
521
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
523
IF( string_a%chars(i) /= string_b(i:i) )THEN
524
s_ne_c = .TRUE.; RETURN
527
IF( la > lb .AND. ANY( string_a%chars(lb+1:la) /= blank ) )THEN
528
s_ne_c = .TRUE.; RETURN
529
ELSEIF( la < lb .AND. blank /= string_b(la+1:lb) )THEN
530
s_ne_c = .TRUE.; RETURN
535
ELEMENTAL FUNCTION c_ne_s(string_a,string_b) ! character/=string
536
CHARACTER(LEN=*),INTENT(IN) :: string_a
537
type(VAR_STR),INTENT(IN) :: string_b
540
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
542
IF( string_a(i:i) /= string_b%chars(i) )THEN
543
c_ne_s = .TRUE.; RETURN
546
IF( la > lb .AND. string_a(lb+1:la) /= blank )THEN
547
c_ne_s = .TRUE.; RETURN
548
ELSEIF( la < lb .AND. ANY( blank /= string_b%chars(la+1:lb) ) )THEN
549
c_ne_s = .TRUE.; RETURN
554
!------ Less-than operators --------------------------------------------------!
555
ELEMENTAL FUNCTION s_lt_s(string_a,string_b) ! string<string
556
type(VAR_STR),INTENT(IN) :: string_a,string_b
559
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
561
IF( string_a%chars(i) < string_b%chars(i) )THEN
562
s_lt_s = .TRUE.; RETURN
563
ELSEIF( string_a%chars(i) > string_b%chars(i) )THEN
564
s_lt_s = .FALSE.; RETURN
569
IF( blank < string_b%chars(i) )THEN
570
s_lt_s = .TRUE.; RETURN
571
ELSEIF( blank > string_b%chars(i) )THEN
572
s_lt_s = .FALSE.; RETURN
575
ELSEIF( la > lb )THEN
577
IF( string_a%chars(i) < blank )THEN
578
s_lt_s = .TRUE.; RETURN
579
ELSEIF( string_a%chars(i) > blank )THEN
580
s_lt_s = .FALSE.; RETURN
587
ELEMENTAL FUNCTION s_lt_c(string_a,string_b) ! string<character
588
type(VAR_STR),INTENT(IN) :: string_a
589
CHARACTER(LEN=*),INTENT(IN) :: string_b
592
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
594
IF( string_a%chars(i) < string_b(i:i) )THEN
595
s_lt_c = .TRUE.; RETURN
596
ELSEIF( string_a%chars(i) > string_b(i:i) )THEN
597
s_lt_c = .FALSE.; RETURN
601
IF( blank < string_b(la+1:lb) )THEN
602
s_lt_c = .TRUE.; RETURN
603
ELSEIF( blank > string_b(la+1:lb) )THEN
604
s_lt_c = .FALSE.; RETURN
606
ELSEIF( la > lb )THEN
608
IF( string_a%chars(i) < blank )THEN
609
s_lt_c = .TRUE.; RETURN
610
ELSEIF( string_a%chars(i) > blank )THEN
611
s_lt_c = .FALSE.; RETURN
618
ELEMENTAL FUNCTION c_lt_s(string_a,string_b) ! character<string
619
CHARACTER(LEN=*),INTENT(IN) :: string_a
620
type(VAR_STR),INTENT(IN) :: string_b
623
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
625
IF( string_a(i:i) < string_b%chars(i) )THEN
626
c_lt_s = .TRUE.; RETURN
627
ELSEIF( string_a(i:i) > string_b%chars(i) )THEN
628
c_lt_s = .FALSE.; RETURN
633
IF( blank < string_b%chars(i) )THEN
634
c_lt_s = .TRUE.; RETURN
635
ELSEIF( blank > string_b%chars(i) )THEN
636
c_lt_s = .FALSE.; RETURN
639
ELSEIF( la > lb )THEN
640
IF( string_a(lb+1:la) < blank )THEN
641
c_lt_s = .TRUE.; RETURN
642
ELSEIF( string_a(lb+1:la) > blank )THEN
643
c_lt_s = .FALSE.; RETURN
649
!------ Less-than-or-equal-to operators --------------------------------------!
650
ELEMENTAL FUNCTION s_le_s(string_a,string_b) ! string<=string
651
type(VAR_STR),INTENT(IN) :: string_a,string_b
654
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
656
IF( string_a%chars(i) < string_b%chars(i) )THEN
657
s_le_s = .TRUE.; RETURN
658
ELSEIF( string_a%chars(i) > string_b%chars(i) )THEN
659
s_le_s = .FALSE.; RETURN
664
IF( blank < string_b%chars(i) )THEN
665
s_le_s = .TRUE.; RETURN
666
ELSEIF( blank > string_b%chars(i) )THEN
667
s_le_s = .FALSE.; RETURN
670
ELSEIF( la > lb )THEN
672
IF( string_a%chars(i) < blank )THEN
673
s_le_s = .TRUE.; RETURN
674
ELSEIF( string_a%chars(i) > blank )THEN
675
s_le_s = .FALSE.; RETURN
682
ELEMENTAL FUNCTION s_le_c(string_a,string_b) ! string<=character
683
type(VAR_STR),INTENT(IN) :: string_a
684
CHARACTER(LEN=*),INTENT(IN) :: string_b
687
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
689
IF( string_a%chars(i) < string_b(i:i) )THEN
690
s_le_c = .TRUE.; RETURN
691
ELSEIF( string_a%chars(i) > string_b(i:i) )THEN
692
s_le_c = .FALSE.; RETURN
696
IF( blank < string_b(la+1:lb) )THEN
697
s_le_c = .TRUE.; RETURN
698
ELSEIF( blank > string_b(la+1:lb) )THEN
699
s_le_c = .FALSE.; RETURN
701
ELSEIF( la > lb )THEN
703
IF( string_a%chars(i) < blank )THEN
704
s_le_c = .TRUE.; RETURN
705
ELSEIF( string_a%chars(i) > blank )THEN
706
s_le_c = .FALSE.; RETURN
713
ELEMENTAL FUNCTION c_le_s(string_a,string_b) ! character<=string
714
CHARACTER(LEN=*),INTENT(IN) :: string_a
715
type(VAR_STR),INTENT(IN) :: string_b
718
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
720
IF( string_a(i:i) < string_b%chars(i) )THEN
721
c_le_s = .TRUE.; RETURN
722
ELSEIF( string_a(i:i) > string_b%chars(i) )THEN
723
c_le_s = .FALSE.; RETURN
728
IF( blank < string_b%chars(i) )THEN
729
c_le_s = .TRUE.; RETURN
730
ELSEIF( blank > string_b%chars(i) )THEN
731
c_le_s = .FALSE.; RETURN
734
ELSEIF( la > lb )THEN
735
IF( string_a(lb+1:la) < blank )THEN
736
c_le_s = .TRUE.; RETURN
737
ELSEIF( string_a(lb+1:la) > blank )THEN
738
c_le_s = .FALSE.; RETURN
744
!------ Greater-than-or-equal-to operators -----------------------------------!
745
ELEMENTAL FUNCTION s_ge_s(string_a,string_b) ! string>=string
746
type(VAR_STR),INTENT(IN) :: string_a,string_b
749
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
751
IF( string_a%chars(i) > string_b%chars(i) )THEN
752
s_ge_s = .TRUE.; RETURN
753
ELSEIF( string_a%chars(i) < string_b%chars(i) )THEN
754
s_ge_s = .FALSE.; RETURN
759
IF( blank > string_b%chars(i) )THEN
760
s_ge_s = .TRUE.; RETURN
761
ELSEIF( blank < string_b%chars(i) )THEN
762
s_ge_s = .FALSE.; RETURN
765
ELSEIF( la > lb )THEN
767
IF( string_a%chars(i) > blank )THEN
768
s_ge_s = .TRUE.; RETURN
769
ELSEIF( string_a%chars(i) < blank )THEN
770
s_ge_s = .FALSE.; RETURN
777
ELEMENTAL FUNCTION s_ge_c(string_a,string_b) ! string>=character
778
type(VAR_STR),INTENT(IN) :: string_a
779
CHARACTER(LEN=*),INTENT(IN) :: string_b
782
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
784
IF( string_a%chars(i) > string_b(i:i) )THEN
785
s_ge_c = .TRUE.; RETURN
786
ELSEIF( string_a%chars(i) < string_b(i:i) )THEN
787
s_ge_c = .FALSE.; RETURN
791
IF( blank > string_b(la+1:lb) )THEN
792
s_ge_c = .TRUE.; RETURN
793
ELSEIF( blank < string_b(la+1:lb) )THEN
794
s_ge_c = .FALSE.; RETURN
796
ELSEIF( la > lb )THEN
798
IF( string_a%chars(i) > blank )THEN
799
s_ge_c = .TRUE.; RETURN
800
ELSEIF( string_a%chars(i) < blank )THEN
801
s_ge_c = .FALSE.; RETURN
808
ELEMENTAL FUNCTION c_ge_s(string_a,string_b) ! character>=string
809
CHARACTER(LEN=*),INTENT(IN) :: string_a
810
type(VAR_STR),INTENT(IN) :: string_b
813
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
815
IF( string_a(i:i) > string_b%chars(i) )THEN
816
c_ge_s = .TRUE.; RETURN
817
ELSEIF( string_a(i:i) < string_b%chars(i) )THEN
818
c_ge_s = .FALSE.; RETURN
823
IF( blank > string_b%chars(i) )THEN
824
c_ge_s = .TRUE.; RETURN
825
ELSEIF( blank < string_b%chars(i) )THEN
826
c_ge_s = .FALSE.; RETURN
829
ELSEIF( la > lb )THEN
830
IF( string_a(lb+1:la) > blank )THEN
831
c_ge_s = .TRUE.; RETURN
832
ELSEIF( string_a(lb+1:la) < blank )THEN
833
c_ge_s = .FALSE.; RETURN
839
!------ Greater-than operators -----------------------------------------------!
840
ELEMENTAL FUNCTION s_gt_s(string_a,string_b) ! string>string
841
type(VAR_STR),INTENT(IN) :: string_a,string_b
844
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
846
IF( string_a%chars(i) > string_b%chars(i) )THEN
847
s_gt_s = .TRUE.; RETURN
848
ELSEIF( string_a%chars(i) < string_b%chars(i) )THEN
849
s_gt_s = .FALSE.; RETURN
854
IF( blank > string_b%chars(i) )THEN
855
s_gt_s = .TRUE.; RETURN
856
ELSEIF( blank < string_b%chars(i) )THEN
857
s_gt_s = .FALSE.; RETURN
860
ELSEIF( la > lb )THEN
862
IF( string_a%chars(i) > blank )THEN
863
s_gt_s = .TRUE.; RETURN
864
ELSEIF( string_a%chars(i) < blank )THEN
865
s_gt_s = .FALSE.; RETURN
872
ELEMENTAL FUNCTION s_gt_c(string_a,string_b) ! string>character
873
type(VAR_STR),INTENT(IN) :: string_a
874
CHARACTER(LEN=*),INTENT(IN) :: string_b
877
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
879
IF( string_a%chars(i) > string_b(i:i) )THEN
880
s_gt_c = .TRUE.; RETURN
881
ELSEIF( string_a%chars(i) < string_b(i:i) )THEN
882
s_gt_c = .FALSE.; RETURN
886
IF( blank > string_b(la+1:lb) )THEN
887
s_gt_c = .TRUE.; RETURN
888
ELSEIF( blank < string_b(la+1:lb) )THEN
889
s_gt_c = .FALSE.; RETURN
891
ELSEIF( la > lb )THEN
893
IF( string_a%chars(i) > blank )THEN
894
s_gt_c = .TRUE.; RETURN
895
ELSEIF( string_a%chars(i) < blank )THEN
896
s_gt_c = .FALSE.; RETURN
903
ELEMENTAL FUNCTION c_gt_s(string_a,string_b) ! character>string
904
CHARACTER(LEN=*),INTENT(IN) :: string_a
905
type(VAR_STR),INTENT(IN) :: string_b
908
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
910
IF( string_a(i:i) > string_b%chars(i) )THEN
911
c_gt_s = .TRUE.; RETURN
912
ELSEIF( string_a(i:i) < string_b%chars(i) )THEN
913
c_gt_s = .FALSE.; RETURN
918
IF( blank > string_b%chars(i) )THEN
919
c_gt_s = .TRUE.; RETURN
920
ELSEIF( blank < string_b%chars(i) )THEN
921
c_gt_s = .FALSE.; RETURN
924
ELSEIF( la > lb )THEN
925
IF( string_a(lb+1:la) > blank )THEN
926
c_gt_s = .TRUE.; RETURN
927
ELSEIF( string_a(lb+1:la) < blank )THEN
928
c_gt_s = .FALSE.; RETURN
934
!----- LLT procedures -------------------------------------------------------!
935
ELEMENTAL FUNCTION s_llt_s(string_a,string_b) ! string_a<string_b ISO-646 ordering
936
type(VAR_STR),INTENT(IN) :: string_a,string_b
938
! Returns TRUE if string_a preceeds string_b in the ISO 646 collating
939
! sequence. Otherwise the result is FALSE. The result is FALSE if both
940
! string_a and string_b are zero length.
942
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
944
IF( LLT(string_a%chars(i),string_b%chars(i)) )THEN
945
s_llt_s = .TRUE.; RETURN
946
ELSEIF( LGT(string_a%chars(i),string_b%chars(i)) )THEN
947
s_llt_s = .FALSE.; RETURN
952
IF( LLT(blank,string_b%chars(i)) )THEN
953
s_llt_s = .TRUE.; RETURN
954
ELSEIF( LGT(blank,string_b%chars(i)) )THEN
955
s_llt_s = .FALSE.; RETURN
958
ELSEIF( la > lb )THEN
960
IF( LLT(string_a%chars(i),blank) )THEN
961
s_llt_s = .TRUE.; RETURN
962
ELSEIF( LGT(string_a%chars(i),blank) )THEN
963
s_llt_s = .FALSE.; RETURN
970
ELEMENTAL FUNCTION s_llt_c(string_a,string_b) ! string_a<string_b ISO-646 ordering
971
type(VAR_STR),INTENT(IN) :: string_a
972
CHARACTER(LEN=*),INTENT(IN) :: string_b
975
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
977
IF( LLT(string_a%chars(i),string_b(i:i)) )THEN
978
s_llt_c = .TRUE.; RETURN
979
ELSEIF( LGT(string_a%chars(i),string_b(i:i)) )THEN
980
s_llt_c = .FALSE.; RETURN
984
IF( LLT(blank,string_b(la+1:lb)) )THEN
985
s_llt_c = .TRUE.; RETURN
986
ELSEIF( LGT(blank,string_b(la+1:lb)) )THEN
987
s_llt_c = .FALSE.; RETURN
989
ELSEIF( la > lb )THEN
991
IF( LLT(string_a%chars(i),blank) )THEN
992
s_llt_c = .TRUE.; RETURN
993
ELSEIF( LGT(string_a%chars(i),blank) )THEN
994
s_llt_c = .FALSE.; RETURN
1001
ELEMENTAL FUNCTION c_llt_s(string_a,string_b) ! string_a,string_b ISO-646 ordering
1002
CHARACTER(LEN=*),INTENT(IN) :: string_a
1003
type(VAR_STR),INTENT(IN) :: string_b
1006
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1008
IF( LLT(string_a(i:i),string_b%chars(i)) )THEN
1009
c_llt_s = .TRUE.; RETURN
1010
ELSEIF( LGT(string_a(i:i),string_b%chars(i)) )THEN
1011
c_llt_s = .FALSE.; RETURN
1016
IF( LLT(blank,string_b%chars(i)) )THEN
1017
c_llt_s = .TRUE.; RETURN
1018
ELSEIF( LGT(blank,string_b%chars(i)) )THEN
1019
c_llt_s = .FALSE.; RETURN
1022
ELSEIF( la > lb )THEN
1023
IF( LLT(string_a(lb+1:la),blank) )THEN
1024
c_llt_s = .TRUE.; RETURN
1025
ELSEIF( LGT(string_a(lb+1:la),blank) )THEN
1026
c_llt_s = .FALSE.; RETURN
1032
!----- LLE procedures -------------------------------------------------------!
1033
ELEMENTAL FUNCTION s_lle_s(string_a,string_b) ! string_a<=string_b ISO-646 ordering
1034
type(VAR_STR),INTENT(IN) :: string_a,string_b
1036
! Returns TRUE if strings are equal or if string_a preceeds string_b in the
1037
! ISO 646 collating sequence. Otherwise the result is FALSE.
1039
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1041
IF( LLT(string_a%chars(i),string_b%chars(i)) )THEN
1042
s_lle_s = .TRUE.; RETURN
1043
ELSEIF( LGT(string_a%chars(i),string_b%chars(i)) )THEN
1044
s_lle_s = .FALSE.; RETURN
1049
IF( LLT(blank,string_b%chars(i)) )THEN
1050
s_lle_s = .TRUE.; RETURN
1051
ELSEIF( LGT(blank,string_b%chars(i)) )THEN
1052
s_lle_s = .FALSE.; RETURN
1055
ELSEIF( la > lb )THEN
1057
IF( LLT(string_a%chars(i),blank) )THEN
1058
s_lle_s = .TRUE.; RETURN
1059
ELSEIF( LGT(string_a%chars(i),blank) )THEN
1060
s_lle_s = .FALSE.; RETURN
1067
ELEMENTAL FUNCTION s_lle_c(string_a,string_b) ! strung_a<=string_b ISO-646 ordering
1068
type(VAR_STR),INTENT(IN) :: string_a
1069
CHARACTER(LEN=*),INTENT(IN) :: string_b
1072
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1074
IF( LLT(string_a%chars(i),string_b(i:i)) )THEN
1075
s_lle_c = .TRUE.; RETURN
1076
ELSEIF( LGT(string_a%chars(i),string_b(i:i)) )THEN
1077
s_lle_c = .FALSE.; RETURN
1081
IF( LLT(blank,string_b(la+1:lb)) )THEN
1082
s_lle_c = .TRUE.; RETURN
1083
ELSEIF( LGT(blank,string_b(la+1:lb)) )THEN
1084
s_lle_c = .FALSE.; RETURN
1086
ELSEIF( la > lb )THEN
1088
IF( LLT(string_a%chars(i),blank) )THEN
1089
s_lle_c = .TRUE.; RETURN
1090
ELSEIF( LGT(string_a%chars(i),blank) )THEN
1091
s_lle_c = .FALSE.; RETURN
1098
ELEMENTAL FUNCTION c_lle_s(string_a,string_b) ! string_a<=string_b ISO-646 ordering
1099
CHARACTER(LEN=*),INTENT(IN) :: string_a
1100
type(VAR_STR),INTENT(IN) :: string_b
1103
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1105
IF( LLT(string_a(i:i),string_b%chars(i)) )THEN
1106
c_lle_s = .TRUE.; RETURN
1107
ELSEIF( LGT(string_a(i:i),string_b%chars(i)) )THEN
1108
c_lle_s = .FALSE.; RETURN
1113
IF( LLT(blank,string_b%chars(i)) )THEN
1114
c_lle_s = .TRUE.; RETURN
1115
ELSEIF( LGT(blank,string_b%chars(i)) )THEN
1116
c_lle_s = .FALSE.; RETURN
1119
ELSEIF( la > lb )THEN
1120
IF( LLT(string_a(lb+1:la),blank) )THEN
1121
c_lle_s = .TRUE.; RETURN
1122
ELSEIF( LGT(string_a(lb+1:la),blank) )THEN
1123
c_lle_s = .FALSE.; RETURN
1129
!----- LGE procedures -------------------------------------------------------!
1130
ELEMENTAL FUNCTION s_lge_s(string_a,string_b) ! string_a>=string_b ISO-646 ordering
1131
type(VAR_STR),INTENT(IN) :: string_a,string_b
1133
! Returns TRUE if strings are equal or if string_a follows string_b in the
1134
! ISO 646 collating sequence. Otherwise the result is FALSE.
1136
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1138
IF( LGT(string_a%chars(i),string_b%chars(i)) )THEN
1139
s_lge_s = .TRUE.; RETURN
1140
ELSEIF( LLT(string_a%chars(i),string_b%chars(i)) )THEN
1141
s_lge_s = .FALSE.; RETURN
1146
IF( LGT(blank,string_b%chars(i)) )THEN
1147
s_lge_s = .TRUE.; RETURN
1148
ELSEIF( LLT(blank,string_b%chars(i)) )THEN
1149
s_lge_s = .FALSE.; RETURN
1152
ELSEIF( la > lb )THEN
1154
IF( LGT(string_a%chars(i),blank) )THEN
1155
s_lge_s = .TRUE.; RETURN
1156
ELSEIF( LLT(string_a%chars(i),blank) )THEN
1157
s_lge_s = .FALSE.; RETURN
1164
ELEMENTAL FUNCTION s_lge_c(string_a,string_b) ! string_a>=string_b ISO-646 ordering
1165
type(VAR_STR),INTENT(IN) :: string_a
1166
CHARACTER(LEN=*),INTENT(IN) :: string_b
1169
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1171
IF( LGT(string_a%chars(i),string_b(i:i)) )THEN
1172
s_lge_c = .TRUE.; RETURN
1173
ELSEIF( LLT(string_a%chars(i),string_b(i:i)) )THEN
1174
s_lge_c = .FALSE.; RETURN
1178
IF( LGT(blank,string_b(la+1:lb)) )THEN
1179
s_lge_c = .TRUE.; RETURN
1180
ELSEIF( LLT(blank,string_b(la+1:lb)) )THEN
1181
s_lge_c = .FALSE.; RETURN
1183
ELSEIF( la > lb )THEN
1185
IF( LGT(string_a%chars(i),blank) )THEN
1186
s_lge_c = .TRUE.; RETURN
1187
ELSEIF( LLT(string_a%chars(i),blank) )THEN
1188
s_lge_c = .FALSE.; RETURN
1195
ELEMENTAL FUNCTION c_lge_s(string_a,string_b) ! string_a>=string_b ISO-646 ordering
1196
CHARACTER(LEN=*),INTENT(IN) :: string_a
1197
type(VAR_STR),INTENT(IN) :: string_b
1200
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1202
IF( LGT(string_a(i:i),string_b%chars(i)) )THEN
1203
c_lge_s = .TRUE.; RETURN
1204
ELSEIF( LLT(string_a(i:i),string_b%chars(i)) )THEN
1205
c_lge_s = .FALSE.; RETURN
1210
IF( LGT(blank,string_b%chars(i)) )THEN
1211
c_lge_s = .TRUE.; RETURN
1212
ELSEIF( LLT(blank,string_b%chars(i)) )THEN
1213
c_lge_s = .FALSE.; RETURN
1216
ELSEIF( la > lb )THEN
1217
IF( LGT(string_a(lb+1:la),blank) )THEN
1218
c_lge_s = .TRUE.; RETURN
1219
ELSEIF( LLT(string_a(lb+1:la),blank) )THEN
1220
c_lge_s = .FALSE.; RETURN
1226
!----- LGT procedures -------------------------------------------------------!
1227
ELEMENTAL FUNCTION s_lgt_s(string_a,string_b) ! string_a>string_b ISO-646 ordering
1228
type(VAR_STR),INTENT(IN) :: string_a,string_b
1230
! Returns TRUE if string_a follows string_b in the ISO 646 collating sequence.
1231
! Otherwise the result is FALSE. The result is FALSE if both string_a and
1232
! string_b are zero length.
1234
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1236
IF( LGT(string_a%chars(i),string_b%chars(i)) )THEN
1237
s_lgt_s = .TRUE.; RETURN
1238
ELSEIF( LLT(string_a%chars(i),string_b%chars(i)) )THEN
1239
s_lgt_s = .FALSE.; RETURN
1244
IF( LGT(blank,string_b%chars(i)) )THEN
1245
s_lgt_s = .TRUE.; RETURN
1246
ELSEIF( LLT(blank,string_b%chars(i)) )THEN
1247
s_lgt_s = .FALSE.; RETURN
1250
ELSEIF( la > lb )THEN
1252
IF( LGT(string_a%chars(i),blank) )THEN
1253
s_lgt_s = .TRUE.; RETURN
1254
ELSEIF( LLT(string_a%chars(i),blank) )THEN
1255
s_lgt_s = .FALSE.; RETURN
1262
ELEMENTAL FUNCTION s_lgt_c(string_a,string_b) ! string_a>string_b ISO-646 ordering
1263
type(VAR_STR),INTENT(IN) :: string_a
1264
CHARACTER(LEN=*),INTENT(IN) :: string_b
1267
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1269
IF( LGT(string_a%chars(i),string_b(i:i)) )THEN
1270
s_lgt_c = .TRUE.; RETURN
1271
ELSEIF( LLT(string_a%chars(i),string_b(i:i)) )THEN
1272
s_lgt_c = .FALSE.; RETURN
1276
IF( LGT(blank,string_b(la+1:lb)) )THEN
1277
s_lgt_c = .TRUE.; RETURN
1278
ELSEIF( LLT(blank,string_b(la+1:lb)) )THEN
1279
s_lgt_c = .FALSE.; RETURN
1281
ELSEIF( la > lb )THEN
1283
IF( LGT(string_a%chars(i),blank) )THEN
1284
s_lgt_c = .TRUE.; RETURN
1285
ELSEIF( LLT(string_a%chars(i),blank) )THEN
1286
s_lgt_c = .FALSE.; RETURN
1293
ELEMENTAL FUNCTION c_lgt_s(string_a,string_b) ! string_a>string_b ISO-646 ordering
1294
CHARACTER(LEN=*),INTENT(IN) :: string_a
1295
type(VAR_STR),INTENT(IN) :: string_b
1298
la = LEN(string_a); lb = LEN(string_b); ls = MIN(la,lb)
1300
IF( LGT(string_a(i:i),string_b%chars(i)) )THEN
1301
c_lgt_s = .TRUE.; RETURN
1302
ELSEIF( LLT(string_a(i:i),string_b%chars(i)) )THEN
1303
c_lgt_s = .FALSE.; RETURN
1308
IF( LGT(blank,string_b%chars(i)) )THEN
1309
c_lgt_s = .TRUE.; RETURN
1310
ELSEIF( LLT(blank,string_b%chars(i)) )THEN
1311
c_lgt_s = .FALSE.; RETURN
1314
ELSEIF( la > lb )THEN
1315
IF( LGT(string_a(lb+1:la),blank) )THEN
1316
c_lgt_s = .TRUE.; RETURN
1317
ELSEIF( LLT(string_a(lb+1:la),blank) )THEN
1318
c_lgt_s = .FALSE.; RETURN
1325
!----- Input string procedure -----------------------------------------------!
1326
SUBROUTINE get_d_eor(string,maxlen,iostat)
1327
type(VAR_STR),INTENT(OUT) :: string
1328
! the string variable to be filled with
1329
! characters read from the
1330
! file connected to the default unit
1331
INTEGER,INTENT(IN),OPTIONAL :: maxlen
1332
! if present indicates the maximum
1333
! number of characters that will be
1334
! read from the file
1335
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1336
! if present used to return the status
1337
! of the data transfer
1338
! if absent errors cause termination
1339
! reads string from the default unit starting at next character in the file
1340
! and terminating at the end of record or after maxlen characters.
1341
CHARACTER(LEN=80) :: buffer
1342
INTEGER :: ist,nch,toread,nb
1343
IF(PRESENT(maxlen))THEN
1348
string = "" ! clears return string N.B. will also deallocate string via the
1349
! assignment operation
1350
DO ! repeatedly read buffer and add to string until EoR
1354
READ(*,FMT='(A)',ADVANCE='NO',EOR=9999,SIZE=nch,IOSTAT=ist) buffer(1:nb)
1356
IF(PRESENT(iostat)) THEN
1360
WRITE(*,*) " Error No.",ist, &
1361
" during READ_STRING of varying string on default unit"
1365
string = string //buffer(1:nb)
1366
toread = toread - nb
1368
IF(PRESENT(iostat)) iostat = 0
1370
9999 string = string //buffer(1:nch)
1371
IF(PRESENT(iostat)) iostat = ist
1372
ENDSUBROUTINE get_d_eor
1374
SUBROUTINE get_u_eor(unit,string,maxlen,iostat)
1375
INTEGER,INTENT(IN) :: unit
1376
! identifies the input unit which must be
1377
! connected for sequential formatted read
1378
type(VAR_STR),INTENT(OUT) :: string
1379
! the string variable to be filled with
1380
! characters read from the
1381
! file connected to the unit
1382
INTEGER,INTENT(IN),OPTIONAL :: maxlen
1383
! if present indicates the maximum
1384
! number of characters that will be
1385
! read from the file
1386
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1387
! if present used to return the status
1388
! of the data transfer
1389
! if absent errors cause termination
1390
! reads string from unit starting at next character in the file and
1391
! terminating at the end of record or after maxlen characters.
1392
CHARACTER(LEN=80) :: buffer
1393
INTEGER :: ist,nch,toread,nb
1394
IF(PRESENT(maxlen))THEN
1399
string="" ! clears return string N.B. will also deallocate string via the
1400
! assignment operation
1401
DO ! repeatedly read buffer and add to string until EoR
1405
READ(unit,FMT='(A)',ADVANCE='NO',EOR=9999,SIZE=nch,IOSTAT=ist) buffer(1:nb)
1407
IF(PRESENT(iostat)) THEN
1411
WRITE(*,*) " Error No.",ist, &
1412
" during READ_STRING of varying string on UNIT ",unit
1416
string = string //buffer(1:nb)
1417
toread = toread - nb
1419
IF(PRESENT(iostat)) iostat = 0
1421
9999 string = string //buffer(1:nch)
1422
IF(PRESENT(iostat)) iostat = ist
1423
ENDSUBROUTINE get_u_eor
1425
SUBROUTINE get_d_tset_s(string,set,separator,maxlen,iostat)
1426
type(VAR_STR),INTENT(OUT) :: string
1427
! the string variable to be filled with
1428
! characters read from the
1429
! file connected to the default unit
1430
type(VAR_STR),INTENT(IN) :: set
1431
! the set of characters which if found in
1432
! the input terminate the read
1433
type(VAR_STR),INTENT(OUT),OPTIONAL :: separator
1434
! the actual separator character from set
1435
! found as the input string terminator
1436
! returned as zero length if termination
1438
INTEGER,INTENT(IN),OPTIONAL :: maxlen
1439
! if present indicates the maximum
1440
! number of characters that will be
1441
! read from the file
1442
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1443
! if present used to return the status
1444
! of the data transfer
1445
! if absent errors cause termination
1446
! reads string from the default unit starting at next character in the file and
1447
! terminating at the end of record, occurance of a character in set,
1448
! or after reading maxlen characters.
1449
CHARACTER :: buffer ! characters must be read one at a time to detect
1450
! first terminator character in set
1451
INTEGER :: ist,toread,lenset
1453
IF(PRESENT(maxlen))THEN
1458
string = "" ! clears return string N.B. will also deallocate string via the
1459
! assignment operation
1460
IF(PRESENT(separator)) separator="" ! clear the separator
1461
readchar:DO ! repeatedly read buffer and add to string
1462
IF(toread <= 0)EXIT readchar ! maxlen reached
1463
READ(*,FMT='(A)',ADVANCE='NO',EOR=9999,IOSTAT=ist) buffer
1465
IF(PRESENT(iostat)) THEN
1469
WRITE(*,*) " Error No.",ist, &
1470
" during GET of varying string on default unit"
1474
! check for occurance of set character in buffer
1476
IF(buffer == set%chars(j))THEN
1477
IF(PRESENT(separator)) separator=buffer
1478
EXIT readchar ! separator terminator found
1481
string = string//buffer
1484
IF(PRESENT(iostat)) iostat = 0
1486
9999 CONTINUE ! EOR terminator read
1487
IF(PRESENT(iostat)) iostat = ist
1488
ENDSUBROUTINE get_d_tset_s
1490
SUBROUTINE get_u_tset_s(unit,string,set,separator,maxlen,iostat)
1491
INTEGER,INTENT(IN) :: unit
1492
! identifies the input unit which must be
1493
! connected for sequential formatted read
1494
type(VAR_STR),INTENT(OUT) :: string
1495
! the string variable to be filled with
1496
! characters read from the
1497
! file connected to the unit
1498
type(VAR_STR),INTENT(IN) :: set
1499
! the set of characters which if found in
1500
! the input terminate the read
1501
type(VAR_STR),INTENT(OUT),OPTIONAL :: separator
1502
! the actual separator character from set
1503
! found as the input string terminator
1504
! returned as zero length if termination
1506
INTEGER,INTENT(IN),OPTIONAL :: maxlen
1507
! if present indicates the maximum
1508
! number of characters that will be
1509
! read from the file
1510
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1511
! if present used to return the status
1512
! of the data transfer
1513
! if absent errors cause termination
1514
! reads string from unit starting at next character in the file and
1515
! terminating at the end of record, occurance of a character in set,
1516
! or after reading maxlen characters.
1517
CHARACTER :: buffer ! characters must be read one at a time to detect
1518
! first terminator character in set
1519
INTEGER :: ist,toread,lenset
1521
IF(PRESENT(maxlen))THEN
1526
string = "" ! clears return string N.B. will also deallocate string via the
1527
! assignment operation
1528
IF(PRESENT(separator)) separator="" ! clear the separator
1529
readchar:DO ! repeatedly read buffer and add to string
1530
IF(toread <= 0)EXIT readchar ! maxlen reached
1531
READ(unit,FMT='(A)',ADVANCE='NO',EOR=9999,IOSTAT=ist) buffer
1533
IF(PRESENT(iostat)) THEN
1537
WRITE(*,*) " Error No.",ist, &
1538
" during GET of varying string on unit ",unit
1542
! check for occurance of set character in buffer
1544
IF(buffer == set%chars(j))THEN
1545
IF(PRESENT(separator)) separator=buffer
1546
EXIT readchar ! separator terminator found
1549
string = string//buffer
1552
IF(PRESENT(iostat)) iostat = 0
1554
9999 CONTINUE ! EOR terminator found
1555
IF(PRESENT(iostat)) iostat = ist
1556
ENDSUBROUTINE get_u_tset_s
1558
SUBROUTINE get_d_tset_c(string,set,separator,maxlen,iostat)
1559
type(VAR_STR),INTENT(OUT) :: string
1560
! the string variable to be filled with
1561
! characters read from the
1562
! file connected to the default unit
1563
CHARACTER(LEN=*),INTENT(IN) :: set
1564
! the set of characters which if found in
1565
! the input terminate the read
1566
type(VAR_STR),INTENT(OUT),OPTIONAL :: separator
1567
! the actual separator character from set
1568
! found as the input string terminator
1569
! returned as zero length if termination
1571
INTEGER,INTENT(IN),OPTIONAL :: maxlen
1572
! if present indicates the maximum
1573
! number of characters that will be
1574
! read from the file
1575
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1576
! if present used to return the status
1577
! of the data transfer
1578
! if absent errors cause termination
1579
! reads string from the default unit starting at next character in the file and
1580
! terminating at the end of record, occurance of a character in set,
1581
! or after reading maxlen characters.
1582
CHARACTER :: buffer ! characters must be read one at a time to detect
1583
! first terminator character in set
1584
INTEGER :: ist,toread,lenset
1586
IF(PRESENT(maxlen))THEN
1591
string = "" ! clears return string N.B. will also deallocate string via the
1592
! assignment operation
1593
IF(PRESENT(separator)) separator="" ! clear separator
1594
readchar:DO ! repeatedly read buffer and add to string
1595
IF(toread <= 0)EXIT readchar ! maxlen reached
1596
READ(*,FMT='(A)',ADVANCE='NO',EOR=9999,IOSTAT=ist) buffer
1598
IF(PRESENT(iostat)) THEN
1602
WRITE(*,*) " Error No.",ist, &
1603
" during GET of varying string on default unit"
1607
! check for occurance of set character in buffer
1609
IF(buffer == set(j:j))THEN
1610
IF(PRESENT(separator)) separator=buffer
1614
string = string//buffer
1617
IF(PRESENT(iostat)) iostat = 0
1619
9999 CONTINUE ! EOR terminator read
1620
IF(PRESENT(iostat)) iostat = ist
1621
ENDSUBROUTINE get_d_tset_c
1623
SUBROUTINE get_u_tset_c(unit,string,set,separator,maxlen,iostat)
1624
INTEGER,INTENT(IN) :: unit
1625
! identifies the input unit which must be
1626
! connected for sequential formatted read
1627
type(VAR_STR),INTENT(OUT) :: string
1628
! the string variable to be filled with
1629
! characters read from the
1630
! file connected to the unit
1631
CHARACTER(LEN=*),INTENT(IN) :: set
1632
! the set of characters which if found in
1633
! the input terminate the read
1634
type(VAR_STR),INTENT(OUT),OPTIONAL :: separator
1635
! the actual separator character from set
1636
! found as the input string terminator
1637
! returned as zero length if termination
1639
INTEGER,INTENT(IN),OPTIONAL :: maxlen
1640
! if present indicates the maximum
1641
! number of characters that will be
1642
! read from the file
1643
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1644
! if present used to return the status
1645
! of the data transfer
1646
! if absent errors cause termination
1647
! reads string from unit starting at next character in the file and
1648
! terminating at the end of record, occurance of a character in set,
1649
! or after reading maxlen characters.
1650
CHARACTER :: buffer ! characters must be read one at a time to detect
1651
! first terminator character in set
1652
INTEGER :: ist,toread,lenset
1654
IF(PRESENT(maxlen))THEN
1659
string = "" ! clears return string N.B. will also deallocate string via the
1660
! assignment operation
1661
IF(PRESENT(separator)) separator="" ! clear separator
1662
readchar:DO ! repeatedly read buffer and add to string
1663
IF(toread <= 0)EXIT readchar ! maxlen reached
1664
READ(unit,FMT='(A)',ADVANCE='NO',EOR=9999,IOSTAT=ist) buffer
1666
IF(PRESENT(iostat)) THEN
1670
WRITE(*,*) " Error No.",ist, &
1671
" during GET of varying string on unit ",unit
1675
! check for occurance of set character in buffer
1677
IF(buffer == set(j:j))THEN
1678
IF(PRESENT(separator)) separator=buffer
1679
EXIT readchar ! separator terminator found
1682
string = string//buffer
1685
IF(PRESENT(iostat)) iostat = 0
1687
9999 CONTINUE ! EOR terminator read
1688
IF(PRESENT(iostat)) iostat = ist
1689
ENDSUBROUTINE get_u_tset_c
1691
!----- Output string procedures ----------------------------------------------!
1692
SUBROUTINE put_d_s(string,iostat)
1693
type(VAR_STR),INTENT(IN) :: string
1694
! the string variable to be appended to
1695
! the current record or to the start of
1696
! the next record if there is no
1698
! uses the default unit
1699
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1700
! if present used to return the status
1701
! of the data transfer
1702
! if absent errors cause termination
1704
WRITE(*,FMT='(A)',ADVANCE='NO',IOSTAT=ist) CHAR(string)
1706
IF(PRESENT(iostat))THEN
1710
WRITE(*,*) " Error No.",ist, &
1711
" during PUT of varying string on default unit"
1715
IF(PRESENT(iostat)) iostat=0
1716
ENDSUBROUTINE put_d_s
1718
SUBROUTINE put_u_s(unit,string,iostat)
1719
INTEGER,INTENT(IN) :: unit
1720
! identifies the output unit which must
1721
! be connected for sequential formatted
1723
type(VAR_STR),INTENT(IN) :: string
1724
! the string variable to be appended to
1725
! the current record or to the start of
1726
! the next record if there is no
1728
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1729
! if present used to return the status
1730
! of the data transfer
1731
! if absent errors cause termination
1733
WRITE(unit,FMT='(A)',ADVANCE='NO',IOSTAT=ist) CHAR(string)
1735
IF(PRESENT(iostat))THEN
1739
WRITE(*,*) " Error No.",ist, &
1740
" during PUT of varying string on UNIT ",unit
1744
IF(PRESENT(iostat)) iostat=0
1745
ENDSUBROUTINE put_u_s
1747
SUBROUTINE put_d_c(string,iostat)
1748
CHARACTER(LEN=*),INTENT(IN) :: string
1749
! the character variable to be appended to
1750
! the current record or to the start of
1751
! the next record if there is no
1753
! uses the default unit
1754
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1755
! if present used to return the status
1756
! of the data transfer
1757
! if absent errors cause termination
1759
WRITE(*,FMT='(A)',ADVANCE='NO',IOSTAT=ist) string
1761
IF(PRESENT(iostat))THEN
1765
WRITE(*,*) " Error No.",ist, &
1766
" during PUT of character on default unit"
1770
IF(PRESENT(iostat)) iostat=0
1771
ENDSUBROUTINE put_d_c
1773
SUBROUTINE put_u_c(unit,string,iostat)
1774
INTEGER,INTENT(IN) :: unit
1775
! identifies the output unit which must
1776
! be connected for sequential formatted
1778
CHARACTER(LEN=*),INTENT(IN) :: string
1779
! the character variable to be appended to
1780
! the current record or to the start of
1781
! the next record if there is no
1783
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1784
! if present used to return the status
1785
! of the data transfer
1786
! if absent errors cause termination
1788
WRITE(unit,FMT='(A)',ADVANCE='NO',IOSTAT=ist) string
1790
IF(PRESENT(iostat))THEN
1794
WRITE(*,*) " Error No.",ist," during PUT of character on UNIT ",unit
1798
IF(PRESENT(iostat)) iostat=0
1799
ENDSUBROUTINE put_u_c
1801
SUBROUTINE putline_d_s(string,iostat)
1802
type(VAR_STR),INTENT(IN) :: string
1803
! the string variable to be appended to
1804
! the current record or to the start of
1805
! the next record if there is no
1807
! uses the default unit
1808
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1809
! if present used to return the status
1810
! of the data transfer
1811
! if absent errors cause termination
1812
! appends the string to the current record and then ends the record
1813
! leaves the file positioned after the record just completed which then
1814
! becomes the previous and last record in the file.
1816
WRITE(*,FMT='(A,/)',ADVANCE='NO',IOSTAT=ist) CHAR(string)
1818
IF(PRESENT(iostat))THEN
1819
iostat = ist; RETURN
1821
WRITE(*,*) " Error No.",ist, &
1822
" during PUT_LINE of varying string on default unit"
1826
IF(PRESENT(iostat)) iostat=0
1827
ENDSUBROUTINE putline_d_s
1829
SUBROUTINE putline_u_s(unit,string,iostat)
1830
INTEGER,INTENT(IN) :: unit
1831
! identifies the output unit which must
1832
! be connected for sequential formatted
1834
type(VAR_STR),INTENT(IN) :: string
1835
! the string variable to be appended to
1836
! the current record or to the start of
1837
! the next record if there is no
1839
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1840
! if present used to return the status
1841
! of the data transfer
1842
! if absent errors cause termination
1843
! appends the string to the current record and then ends the record
1844
! leaves the file positioned after the record just completed which then
1845
! becomes the previous and last record in the file.
1847
WRITE(unit,FMT='(A,/)',ADVANCE='NO',IOSTAT=ist) CHAR(string)
1849
IF(PRESENT(iostat))THEN
1850
iostat = ist; RETURN
1852
WRITE(*,*) " Error No.",ist, &
1853
" during PUT_LINE of varying string on UNIT",unit
1857
IF(PRESENT(iostat)) iostat=0
1858
ENDSUBROUTINE putline_u_s
1860
SUBROUTINE putline_d_c(string,iostat)
1861
CHARACTER(LEN=*),INTENT(IN) :: string
1862
! the character variable to be appended to
1863
! the current record or to the start of
1864
! the next record if there is no
1866
! uses the default unit
1867
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1868
! if present used to return the status
1869
! of the data transfer
1870
! if absent errors cause termination
1871
! appends the string to the current record and then ends the record
1872
! leaves the file positioned after the record just completed which then
1873
! becomes the previous and last record in the file.
1875
WRITE(*,FMT='(A,/)',ADVANCE='NO',IOSTAT=ist) string
1876
IF(PRESENT(iostat))THEN
1879
ELSEIF( ist /= 0 )THEN
1880
WRITE(*,*) " Error No.",ist, &
1881
" during PUT_LINE of character on default unit"
1884
ENDSUBROUTINE putline_d_c
1886
SUBROUTINE putline_u_c(unit,string,iostat)
1887
INTEGER,INTENT(IN) :: unit
1888
! identifies the output unit which must
1889
! be connected for sequential formatted
1891
CHARACTER(LEN=*),INTENT(IN) :: string
1892
! the character variable to be appended to
1893
! the current record or to the start of
1894
! the next record if there is no
1896
INTEGER,INTENT(OUT),OPTIONAL :: iostat
1897
! if present used to return the status
1898
! of the data transfer
1899
! if absent errors cause termination
1900
! appends the string to the current record and then ends the record
1901
! leaves the file positioned after the record just completed which then
1902
! becomes the previous and last record in the file.
1904
WRITE(unit,FMT='(A,/)',ADVANCE='NO',IOSTAT=ist) string
1905
IF(PRESENT(iostat))THEN
1908
ELSEIF( ist /= 0 )THEN
1909
WRITE(*,*) " Error No.",ist, &
1910
" during WRITE_LINE of character on UNIT",unit
1913
ENDSUBROUTINE putline_u_c
1915
!----- Insert procedures ----------------------------------------------------!
1916
ELEMENTAL FUNCTION insert_ss(string,start,substring)
1917
type(VAR_STR) :: insert_ss
1918
type(VAR_STR),INTENT(IN) :: string
1919
INTEGER,INTENT(IN) :: start
1920
type(VAR_STR),INTENT(IN) :: substring
1921
! calculates result string by inserting the substring into string
1922
! beginning at position start pushing the remainder of the string
1923
! to the right and enlarging it accordingly,
1924
! if start is greater than LEN(string) the substring is simply appended
1925
! to string by concatenation. if start is less than 1
1926
! substring is inserted before string, ie. start is treated as if it were 1
1927
CHARACTER,POINTER,DIMENSION(:) :: work
1928
INTEGER :: ip,is,lsub,ls
1929
lsub = LEN(substring); ls = LEN(string)
1932
ALLOCATE(work(1:lsub+ls))
1933
work(1:ip-1) = string%chars(1:ip-1)
1934
work(ip:ip+lsub-1) =substring%chars
1935
work(ip+lsub:lsub+ls) = string%chars(ip:ls)
1936
insert_ss%chars => work
1937
ENDFUNCTION insert_ss
1939
ELEMENTAL FUNCTION insert_sc(string,start,substring)
1940
type(VAR_STR) :: insert_sc
1941
type(VAR_STR),INTENT(IN) :: string
1942
INTEGER,INTENT(IN) :: start
1943
CHARACTER(LEN=*),INTENT(IN) :: substring
1944
! calculates result string by inserting the substring into string
1945
! beginning at position start pushing the remainder of the string
1946
! to the right and enlarging it accordingly,
1947
! if start is greater than LEN(string) the substring is simply appended
1948
! to string by concatenation. if start is less than 1
1949
! substring is inserted before string, ie. start is treated as if it were 1
1950
CHARACTER,POINTER,DIMENSION(:) :: work
1951
INTEGER :: ip,is,lsub,ls
1952
lsub = LEN(substring); ls = LEN(string)
1955
ALLOCATE(work(1:lsub+ls))
1956
work(1:ip-1) = string%chars(1:ip-1)
1958
work(ip-1+i) = substring(i:i)
1960
work(ip+lsub:lsub+ls) = string%chars(ip:ls)
1961
insert_sc%chars => work
1962
ENDFUNCTION insert_sc
1964
ELEMENTAL FUNCTION insert_cs(string,start,substring)
1965
type(VAR_STR) :: insert_cs
1966
CHARACTER(LEN=*),INTENT(IN) :: string
1967
INTEGER,INTENT(IN) :: start
1968
type(VAR_STR),INTENT(IN) :: substring
1969
! calculates result string by inserting the substring into string
1970
! beginning at position start pushing the remainder of the string
1971
! to the right and enlarging it accordingly,
1972
! if start is greater than LEN(string) the substring is simply appended
1973
! to string by concatenation. if start is less than 1
1974
! substring is inserted before string, ie. start is treated as if it were 1
1975
CHARACTER,POINTER,DIMENSION(:) :: work
1976
INTEGER :: ip,is,lsub,ls
1977
lsub = LEN(substring); ls = LEN(string)
1980
ALLOCATE(work(1:lsub+ls))
1982
work(i) = string(i:i)
1984
work(ip:ip+lsub-1) =substring%chars
1986
work(i+lsub) = string(i:i)
1988
insert_cs%chars => work
1989
ENDFUNCTION insert_cs
1991
ELEMENTAL FUNCTION insert_cc(string,start,substring)
1992
type(VAR_STR) :: insert_cc
1993
CHARACTER(LEN=*),INTENT(IN) :: string
1994
INTEGER,INTENT(IN) :: start
1995
CHARACTER(LEN=*),INTENT(IN) :: substring
1996
! calculates result string by inserting the substring into string
1997
! beginning at position start pushing the remainder of the string
1998
! to the right and enlarging it accordingly,
1999
! if start is greater than LEN(string) the substring is simply appended
2000
! to string by concatenation. if start is less than 1
2001
! substring is inserted before string, ie. start is treated as if it were 1
2002
CHARACTER,POINTER,DIMENSION(:) :: work
2003
INTEGER :: ip,is,lsub,ls
2004
lsub = LEN(substring); ls = LEN(string)
2007
ALLOCATE(work(1:lsub+ls))
2009
work(i) = string(i:i)
2012
work(ip-1+i) = substring(i:i)
2015
work(i+lsub) = string(i:i)
2017
insert_cc%chars => work
2018
ENDFUNCTION insert_cc
2020
!----- Replace procedures ---------------------------------------------------!
2021
ELEMENTAL FUNCTION replace_ss(string,start,substring)
2022
type(VAR_STR) :: replace_ss
2023
type(VAR_STR),INTENT(IN) :: string
2024
INTEGER,INTENT(IN) :: start
2025
type(VAR_STR),INTENT(IN) :: substring
2026
! calculates the result string by the following actions:
2027
! inserts the substring into string beginning at position
2028
! start replacing the following LEN(substring) characters of the string
2029
! and enlarging string if necessary. if start is greater than LEN(string)
2030
! substring is simply appended to string by concatenation. If start is less
2031
! than 1, substring replaces characters in string starting at 1
2032
CHARACTER,POINTER,DIMENSION(:) :: work
2033
INTEGER :: ip,is,nw,lsub,ls
2034
lsub = LEN(substring); ls = LEN(string)
2037
nw = MAX(ls,ip+lsub-1)
2038
ALLOCATE(work(1:nw))
2039
work(1:ip-1) = string%chars(1:ip-1)
2040
work(ip:ip+lsub-1) = substring%chars
2041
work(ip+lsub:nw) = string%chars(ip+lsub:ls)
2042
replace_ss%chars => work
2043
ENDFUNCTION replace_ss
2045
ELEMENTAL FUNCTION replace_ss_sf(string,start,finish,substring)
2046
type(VAR_STR) :: replace_ss_sf
2047
type(VAR_STR),INTENT(IN) :: string
2048
INTEGER,INTENT(IN) :: start,finish
2049
type(VAR_STR),INTENT(IN) :: substring
2050
! calculates the result string by the following actions:
2051
! inserts the substring into string beginning at position
2052
! start replacing the following finish-start+1 characters of the string
2053
! and enlarging or shrinking the string if necessary.
2054
! If start is greater than LEN(string) substring is simply appended to string
2055
! by concatenation. If start is less than 1, start = 1 is used
2056
! If finish is greater than LEN(string), finish = LEN(string) is used
2057
! If finish is less than start, substring is inserted before start
2058
CHARACTER,POINTER,DIMENSION(:) :: work
2059
INTEGER :: ip,is,if,nw,lsub,ls
2060
lsub = LEN(substring); ls = LEN(string)
2063
if = MAX(ip-1,MIN(finish,ls))
2064
nw = lsub + ls - if+ip-1
2065
ALLOCATE(work(1:nw))
2066
work(1:ip-1) = string%chars(1:ip-1)
2067
work(ip:ip+lsub-1) = substring%chars
2068
work(ip+lsub:nw) = string%chars(if+1:ls)
2069
replace_ss_sf%chars => work
2070
ENDFUNCTION replace_ss_sf
2072
ELEMENTAL FUNCTION replace_sc(string,start,substring)
2073
type(VAR_STR) :: replace_sc
2074
type(VAR_STR),INTENT(IN) :: string
2075
INTEGER,INTENT(IN) :: start
2076
CHARACTER(LEN=*),INTENT(IN) :: substring
2077
! calculates the result string by the following actions:
2078
! inserts the characters from substring into string beginning at position
2079
! start replacing the following LEN(substring) characters of the string
2080
! and enlarging string if necessary. If start is greater than LEN(string)
2081
! substring is simply appended to string by concatenation. If start is less
2082
! than 1, substring replaces characters in string starting at 1
2083
CHARACTER,POINTER,DIMENSION(:) :: work
2084
INTEGER :: ip,is,nw,lsub,ls
2085
lsub = LEN(substring); ls = LEN(string)
2088
nw = MAX(ls,ip+lsub-1)
2089
ALLOCATE(work(1:nw))
2090
work(1:ip-1) = string%chars(1:ip-1)
2092
work(ip-1+i) = substring(i:i)
2094
work(ip+lsub:nw) = string%chars(ip+lsub:ls)
2095
replace_sc%chars => work
2096
ENDFUNCTION replace_sc
2098
ELEMENTAL FUNCTION replace_sc_sf(string,start,finish,substring)
2099
type(VAR_STR) :: replace_sc_sf
2100
type(VAR_STR),INTENT(IN) :: string
2101
INTEGER,INTENT(IN) :: start,finish
2102
CHARACTER(LEN=*),INTENT(IN) :: substring
2103
! calculates the result string by the following actions:
2104
! inserts the substring into string beginning at position
2105
! start replacing the following finish-start+1 characters of the string
2106
! and enlarging or shrinking the string if necessary.
2107
! If start is greater than LEN(string) substring is simply appended to string
2108
! by concatenation. If start is less than 1, start = 1 is used
2109
! If finish is greater than LEN(string), finish = LEN(string) is used
2110
! If finish is less than start, substring is inserted before start
2111
CHARACTER,POINTER,DIMENSION(:) :: work
2112
INTEGER :: ip,is,if,nw,lsub,ls
2113
lsub = LEN(substring); ls = LEN(string)
2116
if = MAX(ip-1,MIN(finish,ls))
2117
nw = lsub + ls - if+ip-1
2118
ALLOCATE(work(1:nw))
2119
work(1:ip-1) = string%chars(1:ip-1)
2121
work(ip-1+i) = substring(i:i)
2123
work(ip+lsub:nw) = string%chars(if+1:ls)
2124
replace_sc_sf%chars => work
2125
ENDFUNCTION replace_sc_sf
2127
ELEMENTAL FUNCTION replace_cs(string,start,substring)
2128
type(VAR_STR) :: replace_cs
2129
CHARACTER(LEN=*),INTENT(IN) :: string
2130
INTEGER,INTENT(IN) :: start
2131
type(VAR_STR),INTENT(IN) :: substring
2132
! calculates the result string by the following actions:
2133
! inserts the substring into string beginning at position
2134
! start replacing the following LEN(substring) characters of the string
2135
! and enlarging string if necessary. if start is greater than LEN(string)
2136
! substring is simply appended to string by concatenation. If start is less
2137
! than 1, substring replaces characters in string starting at 1
2138
CHARACTER,POINTER,DIMENSION(:) :: work
2139
INTEGER :: ip,is,nw,lsub,ls
2140
lsub = LEN(substring); ls = LEN(string)
2143
nw = MAX(ls,ip+lsub-1)
2144
ALLOCATE(work(1:nw))
2146
work(i) = string(i:i)
2148
work(ip:ip+lsub-1) = substring%chars
2150
work(i) = string(i:i)
2152
replace_cs%chars => work
2153
ENDFUNCTION replace_cs
2155
ELEMENTAL FUNCTION replace_cs_sf(string,start,finish,substring)
2156
type(VAR_STR) :: replace_cs_sf
2157
CHARACTER(LEN=*),INTENT(IN) :: string
2158
INTEGER,INTENT(IN) :: start,finish
2159
type(VAR_STR),INTENT(IN) :: substring
2160
! calculates the result string by the following actions:
2161
! inserts the substring into string beginning at position
2162
! start replacing the following finish-start+1 characters of the string
2163
! and enlarging or shrinking the string if necessary.
2164
! If start is greater than LEN(string) substring is simply appended to string
2165
! by concatenation. If start is less than 1, start = 1 is used
2166
! If finish is greater than LEN(string), finish = LEN(string) is used
2167
! If finish is less than start, substring is inserted before start
2168
CHARACTER,POINTER,DIMENSION(:) :: work
2169
INTEGER :: ip,is,if,nw,lsub,ls
2170
lsub = LEN(substring); ls = LEN(string)
2173
if = MAX(ip-1,MIN(finish,ls))
2174
nw = lsub + ls - if+ip-1
2175
ALLOCATE(work(1:nw))
2177
work(i) = string(i:i)
2179
work(ip:ip+lsub-1) = substring%chars
2181
work(i+ip+lsub-1) = string(if+i:if+i)
2183
replace_cs_sf%chars => work
2184
ENDFUNCTION replace_cs_sf
2186
ELEMENTAL FUNCTION replace_cc(string,start,substring)
2187
type(VAR_STR) :: replace_cc
2188
CHARACTER(LEN=*),INTENT(IN) :: string
2189
INTEGER,INTENT(IN) :: start
2190
CHARACTER(LEN=*),INTENT(IN) :: substring
2191
! calculates the result string by the following actions:
2192
! inserts the characters from substring into string beginning at position
2193
! start replacing the following LEN(substring) characters of the string
2194
! and enlarging string if necessary. If start is greater than LEN(string)
2195
! substring is simply appended to string by concatenation. If start is less
2196
! than 1, substring replaces characters in string starting at 1
2197
CHARACTER,POINTER,DIMENSION(:) :: work
2198
INTEGER :: ip,is,nw,lsub,ls
2199
lsub = LEN(substring); ls = LEN(string)
2202
nw = MAX(ls,ip+lsub-1)
2203
ALLOCATE(work(1:nw))
2205
work(i) = string(i:i)
2208
work(ip-1+i) = substring(i:i)
2211
work(i) = string(i:i)
2213
replace_cc%chars => work
2214
ENDFUNCTION replace_cc
2216
ELEMENTAL FUNCTION replace_cc_sf(string,start,finish,substring)
2217
type(VAR_STR) :: replace_cc_sf
2218
CHARACTER(LEN=*),INTENT(IN) :: string
2219
INTEGER,INTENT(IN) :: start,finish
2220
CHARACTER(LEN=*),INTENT(IN) :: substring
2221
! calculates the result string by the following actions:
2222
! inserts the substring into string beginning at position
2223
! start replacing the following finish-start+1 characters of the string
2224
! and enlarging or shrinking the string if necessary.
2225
! If start is greater than LEN(string) substring is simply appended to string
2226
! by concatenation. If start is less than 1, start = 1 is used
2227
! If finish is greater than LEN(string), finish = LEN(string) is used
2228
! If finish is less than start, substring is inserted before start
2229
CHARACTER,POINTER,DIMENSION(:) :: work
2230
INTEGER :: ip,is,if,nw,lsub,ls
2231
lsub = LEN(substring); ls = LEN(string)
2234
if = MAX(ip-1,MIN(finish,ls))
2235
nw = lsub + ls - if+ip-1
2236
ALLOCATE(work(1:nw))
2238
work(i) = string(i:i)
2241
work(i+ip-1) = substring(i:i)
2244
work(i+ip+lsub-1) = string(if+i:if+i)
2246
replace_cc_sf%chars => work
2247
ENDFUNCTION replace_cc_sf
2249
ELEMENTAL FUNCTION replace_sss(string,target,substring,every,back)
2250
type(VAR_STR) :: replace_sss
2251
type(VAR_STR),INTENT(IN) :: string,target,substring
2252
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2253
! calculates the result string by the following actions:
2254
! searches for occurences of target in string, and replaces these with
2255
! substring. if back present with value true search is backward otherwise
2256
! search is done forward. if every present with value true all occurences
2257
! of target in string are replaced, otherwise only the first found is
2258
! replaced. if target is not found the result is the same as string.
2259
LOGICAL :: dir_switch, rep_search
2260
CHARACTER,DIMENSION(:),POINTER :: work,temp
2261
INTEGER :: ls,lt,lsub,ipos,ipow
2262
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2265
ALLOCATE(replace_sss%chars(1:lsub))
2266
replace_sss%chars = substring%chars
2269
ALLOCATE(replace_sss%chars(1:ls))
2270
replace_sss%chars = string%chars
2274
ALLOCATE(work(1:ls)); work = string%chars
2275
IF( PRESENT(back) )THEN
2278
dir_switch = .FALSE.
2280
IF( PRESENT(every) )THEN
2283
rep_search = .FALSE.
2285
IF( dir_switch )THEN ! backwards search
2288
IF( ipos < 1 )EXIT ! search past start of string
2289
! test for occurance of target in string at this position
2290
IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN
2291
! match found allocate space for string with this occurance of
2292
! target replaced by substring
2293
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2294
! copy work into temp replacing this occurance of target by
2296
temp(1:ipos-1) = work(1:ipos-1)
2297
temp(ipos:ipos+lsub-1) = substring%chars
2298
temp(ipos+lsub:) = work(ipos+lt:)
2299
work => temp ! make new version of work point at the temp space
2300
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2301
! move search and replacement positions over the effected positions
2306
ELSE ! forward search
2309
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2310
! test for occurance of target in string at this position
2311
IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN
2312
! match found allocate space for string with this occurance of
2313
! target replaced by substring
2314
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2315
! copy work into temp replacing this occurance of target by
2317
temp(1:ipow-1) = work(1:ipow-1)
2318
temp(ipow:ipow+lsub-1) = substring%chars
2319
temp(ipow+lsub:) = work(ipow+lt:)
2320
work => temp ! make new version of work point at the temp space
2321
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2322
! move search and replacement positions over the effected positions
2323
ipos = ipos+lt-1; ipow = ipow+lsub-1
2325
ipos=ipos+1; ipow=ipow+1
2328
replace_sss%chars => work
2329
ENDFUNCTION replace_sss
2331
ELEMENTAL FUNCTION replace_ssc(string,target,substring,every,back)
2332
type(VAR_STR) :: replace_ssc
2333
type(VAR_STR),INTENT(IN) :: string,target
2334
CHARACTER(LEN=*),INTENT(IN) :: substring
2335
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2336
! calculates the result string by the following actions:
2337
! searches for occurences of target in string, and replaces these with
2338
! substring. if back present with value true search is backward otherwise
2339
! search is done forward. if every present with value true all occurences
2340
! of target in string are replaced, otherwise only the first found is
2341
! replaced. if target is not found the result is the same as string.
2342
LOGICAL :: dir_switch, rep_search
2343
CHARACTER,DIMENSION(:),POINTER :: work,temp
2344
INTEGER :: ls,lt,lsub,ipos,ipow
2345
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2348
ALLOCATE(replace_ssc%chars(1:lsub))
2350
replace_ssc%chars(i) = substring(i:i)
2354
ALLOCATE(replace_ssc%chars(1:ls))
2355
replace_ssc%chars = string%chars
2359
ALLOCATE(work(1:ls)); work = string%chars
2360
IF( PRESENT(back) )THEN
2363
dir_switch = .FALSE.
2365
IF( PRESENT(every) )THEN
2368
rep_search = .FALSE.
2370
IF( dir_switch )THEN ! backwards search
2373
IF( ipos < 1 )EXIT ! search past start of string
2374
! test for occurance of target in string at this position
2375
IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN
2376
! match found allocate space for string with this occurance of
2377
! target replaced by substring
2378
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2379
! copy work into temp replacing this occurance of target by
2381
temp(1:ipos-1) = work(1:ipos-1)
2383
temp(i+ipos-1) = substring(i:i)
2385
temp(ipos+lsub:) = work(ipos+lt:)
2386
work => temp ! make new version of work point at the temp space
2387
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2388
! move search and replacement positions over the effected positions
2393
ELSE ! forward search
2396
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2397
! test for occurance of target in string at this position
2398
IF( ALL(string%chars(ipos:ipos+lt-1) == target%chars) )THEN
2399
! match found allocate space for string with this occurance of
2400
! target replaced by substring
2401
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2402
! copy work into temp replacing this occurance of target by
2404
temp(1:ipow-1) = work(1:ipow-1)
2406
temp(i+ipow-1) = substring(i:i)
2408
temp(ipow+lsub:) = work(ipow+lt:)
2409
work => temp ! make new version of work point at the temp space
2410
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2411
! move search and replacement positions over the effected positions
2412
ipos = ipos+lt-1; ipow = ipow+lsub-1
2414
ipos=ipos+1; ipow=ipow+1
2417
replace_ssc%chars => work
2418
ENDFUNCTION replace_ssc
2420
ELEMENTAL FUNCTION replace_scs(string,target,substring,every,back)
2421
type(VAR_STR) :: replace_scs
2422
type(VAR_STR),INTENT(IN) :: string,substring
2423
CHARACTER(LEN=*),INTENT(IN) :: target
2424
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2425
! calculates the result string by the following actions:
2426
! searches for occurences of target in string, and replaces these with
2427
! substring. if back present with value true search is backward otherwise
2428
! search is done forward. if every present with value true all accurences
2429
! of target in string are replaced, otherwise only the first found is
2430
! replaced. if target is not found the result is the same as string.
2431
LOGICAL :: dir_switch, rep_search
2432
CHARACTER,DIMENSION(:),POINTER :: work,temp,tget
2433
INTEGER :: ls,lt,lsub,ipos,ipow
2434
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2437
ALLOCATE(replace_scs%chars(1:lsub))
2438
replace_scs%chars = substring%chars
2441
ALLOCATE(replace_scs%chars(1:ls))
2442
replace_scs%chars = string%chars
2446
ALLOCATE(work(1:ls)); work = string%chars
2447
ALLOCATE(tget(1:lt))
2449
tget(i) = target(i:i)
2451
IF( PRESENT(back) )THEN
2454
dir_switch = .FALSE.
2456
IF( PRESENT(every) )THEN
2459
rep_search = .FALSE.
2461
IF( dir_switch )THEN ! backwards search
2464
IF( ipos < 1 )EXIT ! search past start of string
2465
! test for occurance of target in string at this position
2466
IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN
2467
! match found allocate space for string with this occurance of
2468
! target replaced by substring
2469
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2470
! copy work into temp replacing this occurance of target by
2472
temp(1:ipos-1) = work(1:ipos-1)
2473
temp(ipos:ipos+lsub-1) = substring%chars
2474
temp(ipos+lsub:) = work(ipos+lt:)
2475
work => temp ! make new version of work point at the temp space
2476
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2477
! move search and replacement positions over the effected positions
2482
ELSE ! forward search
2485
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2486
! test for occurance of target in string at this position
2487
IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN
2488
! match found allocate space for string with this occurance of
2489
! target replaced by substring
2490
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2491
! copy work into temp replacing this occurance of target by
2493
temp(1:ipow-1) = work(1:ipow-1)
2494
temp(ipow:ipow+lsub-1) = substring%chars
2495
temp(ipow+lsub:) = work(ipow+lt:)
2496
work => temp ! make new version of work point at the temp space
2497
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2498
! move search and replacement positions over the effected positions
2499
ipos = ipos+lt-1; ipow = ipow+lsub-1
2501
ipos=ipos+1; ipow=ipow+1
2504
replace_scs%chars => work
2505
ENDFUNCTION replace_scs
2507
ELEMENTAL FUNCTION replace_scc(string,target,substring,every,back)
2508
type(VAR_STR) :: replace_scc
2509
type(VAR_STR),INTENT(IN) :: string
2510
CHARACTER(LEN=*),INTENT(IN) :: target,substring
2511
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2512
! calculates the result string by the following actions:
2513
! searches for occurences of target in string, and replaces these with
2514
! substring. if back present with value true search is backward otherwise
2515
! search is done forward. if every present with value true all accurences
2516
! of target in string are replaced, otherwise only the first found is
2517
! replaced. if target is not found the result is the same as string.
2518
LOGICAL :: dir_switch, rep_search
2519
CHARACTER,DIMENSION(:),POINTER :: work,temp,tget
2520
INTEGER :: ls,lt,lsub,ipos,ipow
2521
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2524
ALLOCATE(replace_scc%chars(1:lsub))
2526
replace_scc%chars(i) = substring(i:i)
2530
ALLOCATE(replace_scc%chars(1:ls))
2531
replace_scc%chars = string%chars
2535
ALLOCATE(work(1:ls)); work = string%chars
2536
ALLOCATE(tget(1:lt))
2538
tget(i) = target(i:i)
2540
IF( PRESENT(back) )THEN
2543
dir_switch = .FALSE.
2545
IF( PRESENT(every) )THEN
2548
rep_search = .FALSE.
2550
IF( dir_switch )THEN ! backwards search
2553
IF( ipos < 1 )EXIT ! search past start of string
2554
! test for occurance of target in string at this position
2555
IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN
2556
! match found allocate space for string with this occurance of
2557
! target replaced by substring
2558
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2559
! copy work into temp replacing this occurance of target by
2561
temp(1:ipos-1) = work(1:ipos-1)
2563
temp(i+ipos-1) = substring(i:i)
2565
temp(ipos+lsub:) = work(ipos+lt:)
2566
work => temp ! make new version of work point at the temp space
2567
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2568
! move search and replacement positions over the effected positions
2573
ELSE ! forward search
2576
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2577
! test for occurance of target in string at this position
2578
IF( ALL(string%chars(ipos:ipos+lt-1) == tget) )THEN
2579
! match found allocate space for string with this occurance of
2580
! target replaced by substring
2581
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2582
! copy work into temp replacing this occurance of target by
2584
temp(1:ipow-1) = work(1:ipow-1)
2586
temp(i+ipow-1) = substring(i:i)
2588
temp(ipow+lsub:) = work(ipow+lt:)
2589
work => temp ! make new version of work point at the temp space
2590
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2591
! move search and replacement positions over the effected positions
2592
ipos = ipos+lt-1; ipow = ipow+lsub-1
2594
ipos=ipos+1; ipow=ipow+1
2597
replace_scc%chars => work
2598
ENDFUNCTION replace_scc
2600
ELEMENTAL FUNCTION replace_css(string,target,substring,every,back)
2601
type(VAR_STR) :: replace_css
2602
CHARACTER(LEN=*),INTENT(IN) :: string
2603
type(VAR_STR),INTENT(IN) :: target,substring
2604
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2605
! calculates the result string by the following actions:
2606
! searches for occurences of target in string, and replaces these with
2607
! substring. if back present with value true search is backward otherwise
2608
! search is done forward. if every present with value true all accurences
2609
! of target in string are replaced, otherwise only the first found is
2610
! replaced. if target is not found the result is the same as string.
2611
LOGICAL :: dir_switch, rep_search
2612
CHARACTER,DIMENSION(:),POINTER :: work,temp,str
2613
INTEGER :: ls,lt,lsub,ipos,ipow
2614
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2617
ALLOCATE(replace_css%chars(1:lsub))
2618
replace_css%chars = substring%chars
2621
ALLOCATE(replace_css%chars(1:ls))
2623
replace_css%chars(i) = string(i:i)
2628
ALLOCATE(work(1:ls)); ALLOCATE(str(1:ls))
2630
str(i) = string(i:i)
2633
IF( PRESENT(back) )THEN
2636
dir_switch = .FALSE.
2638
IF( PRESENT(every) )THEN
2641
rep_search = .FALSE.
2643
IF( dir_switch )THEN ! backwards search
2646
IF( ipos < 1 )EXIT ! search past start of string
2647
! test for occurance of target in string at this position
2648
IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN
2649
! match found allocate space for string with this occurance of
2650
! target replaced by substring
2651
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2652
! copy work into temp replacing this occurance of target by
2654
temp(1:ipos-1) = work(1:ipos-1)
2655
temp(ipos:ipos+lsub-1) = substring%chars
2656
temp(ipos+lsub:) = work(ipos+lt:)
2657
work => temp ! make new version of work point at the temp space
2658
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2659
! move search and replacement positions over the effected positions
2664
ELSE ! forward search
2667
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2668
! test for occurance of target in string at this position
2669
IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN
2670
! match found allocate space for string with this occurance of
2671
! target replaced by substring
2672
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2673
! copy work into temp replacing this occurance of target by
2675
temp(1:ipow-1) = work(1:ipow-1)
2676
temp(ipow:ipow+lsub-1) = substring%chars
2677
temp(ipow+lsub:) = work(ipow+lt:)
2678
work => temp ! make new version of work point at the temp space
2679
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2680
! move search and replacement positions over the effected positions
2681
ipos = ipos+lt-1; ipow = ipow+lsub-1
2683
ipos=ipos+1; ipow=ipow+1
2686
replace_css%chars => work
2687
ENDFUNCTION replace_css
2689
ELEMENTAL FUNCTION replace_csc(string,target,substring,every,back)
2690
type(VAR_STR) :: replace_csc
2691
type(VAR_STR),INTENT(IN) :: target
2692
CHARACTER(LEN=*),INTENT(IN) :: string,substring
2693
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2694
! calculates the result string by the following actions:
2695
! searches for occurences of target in string, and replaces these with
2696
! substring. if back present with value true search is backward otherwise
2697
! search is done forward. if every present with value true all accurences
2698
! of target in string are replaced, otherwise only the first found is
2699
! replaced. if target is not found the result is the same as string.
2700
LOGICAL :: dir_switch, rep_search
2701
CHARACTER,DIMENSION(:),POINTER :: work,temp,str
2702
INTEGER :: ls,lt,lsub,ipos,ipow
2703
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2706
ALLOCATE(replace_csc%chars(1:lsub))
2708
replace_csc%chars(i) = substring(i:i)
2712
ALLOCATE(replace_csc%chars(1:ls))
2714
replace_csc%chars(i) = string(i:i)
2719
ALLOCATE(work(1:ls)); ALLOCATE(str(1:ls))
2721
str(i) = string(i:i)
2724
IF( PRESENT(back) )THEN
2727
dir_switch = .FALSE.
2729
IF( PRESENT(every) )THEN
2732
rep_search = .FALSE.
2734
IF( dir_switch )THEN ! backwards search
2737
IF( ipos < 1 )EXIT ! search past start of string
2738
! test for occurance of target in string at this position
2739
IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN
2740
! match found allocate space for string with this occurance of
2741
! target replaced by substring
2742
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2743
! copy work into temp replacing this occurance of target by
2745
temp(1:ipos-1) = work(1:ipos-1)
2747
temp(i+ipos-1) = substring(i:i)
2749
temp(ipos+lsub:) = work(ipos+lt:)
2750
work => temp ! make new version of work point at the temp space
2751
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2752
! move search and replacement positions over the effected positions
2757
ELSE ! forward search
2760
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2761
! test for occurance of target in string at this position
2762
IF( ALL(str(ipos:ipos+lt-1) == target%chars) )THEN
2763
! match found allocate space for string with this occurance of
2764
! target replaced by substring
2765
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2766
! copy work into temp replacing this occurance of target by
2768
temp(1:ipow-1) = work(1:ipow-1)
2770
temp(i+ipow-1) = substring(i:i)
2772
temp(ipow+lsub:) = work(ipow+lt:)
2773
work => temp ! make new version of work point at the temp space
2774
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2775
! move search and replacement positions over the effected positions
2776
ipos = ipos+lt-1; ipow = ipow+lsub-1
2778
ipos=ipos+1; ipow=ipow+1
2781
replace_csc%chars => work
2782
ENDFUNCTION replace_csc
2784
ELEMENTAL FUNCTION replace_ccs(string,target,substring,every,back)
2785
type(VAR_STR) :: replace_ccs
2786
type(VAR_STR),INTENT(IN) :: substring
2787
CHARACTER(LEN=*),INTENT(IN) :: string,target
2788
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2789
! calculates the result string by the following actions:
2790
! searches for occurences of target in string, and replaces these with
2791
! substring. if back present with value true search is backward otherwise
2792
! search is done forward. if every present with value true all accurences
2793
! of target in string are replaced, otherwise only the first found is
2794
! replaced. if target is not found the result is the same as string.
2795
LOGICAL :: dir_switch, rep_search
2796
CHARACTER,DIMENSION(:),POINTER :: work,temp
2797
INTEGER :: ls,lt,lsub,ipos,ipow
2798
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2801
ALLOCATE(replace_ccs%chars(1:lsub))
2802
replace_ccs%chars = substring%chars
2805
ALLOCATE(replace_ccs%chars(1:ls))
2807
replace_ccs%chars(i) = string(i:i)
2812
ALLOCATE(work(1:ls))
2814
work(i) = string(i:i)
2816
IF( PRESENT(back) )THEN
2819
dir_switch = .FALSE.
2821
IF( PRESENT(every) )THEN
2824
rep_search = .FALSE.
2826
IF( dir_switch )THEN ! backwards search
2829
IF( ipos < 1 )EXIT ! search past start of string
2830
! test for occurance of target in string at this position
2831
IF( string(ipos:ipos+lt-1) == target )THEN
2832
! match found allocate space for string with this occurance of
2833
! target replaced by substring
2834
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2835
! copy work into temp replacing this occurance of target by
2837
temp(1:ipos-1) = work(1:ipos-1)
2838
temp(ipos:ipos+lsub-1) = substring%chars
2839
temp(ipos+lsub:) = work(ipos+lt:)
2840
work => temp ! make new version of work point at the temp space
2841
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2842
! move search and replacement positions over the effected positions
2847
ELSE ! forward search
2850
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2851
! test for occurance of target in string at this position
2852
IF( string(ipos:ipos+lt-1) == target )THEN
2853
! match found allocate space for string with this occurance of
2854
! target replaced by substring
2855
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2856
! copy work into temp replacing this occurance of target by
2858
temp(1:ipow-1) = work(1:ipow-1)
2859
temp(ipow:ipow+lsub-1) = substring%chars
2860
temp(ipow+lsub:) = work(ipow+lt:)
2861
work => temp ! make new version of work point at the temp space
2862
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2863
! move search and replacement positions over the effected positions
2864
ipos = ipos+lt-1; ipow = ipow+lsub-1
2866
ipos=ipos+1; ipow=ipow+1
2869
replace_ccs%chars => work
2870
ENDFUNCTION replace_ccs
2872
ELEMENTAL FUNCTION replace_ccc(string,target,substring,every,back)
2873
type(VAR_STR) :: replace_ccc
2874
CHARACTER(LEN=*),INTENT(IN) :: string,target,substring
2875
LOGICAL,INTENT(IN),OPTIONAL :: every,back
2876
! calculates the result string by the following actions:
2877
! searches for occurences of target in string, and replaces these with
2878
! substring. if back present with value true search is backward otherwise
2879
! search is done forward. if every present with value true all accurences
2880
! of target in string are replaced, otherwise only the first found is
2881
! replaced. if target is not found the result is the same as string.
2882
LOGICAL :: dir_switch, rep_search
2883
CHARACTER,DIMENSION(:),POINTER :: work,temp
2884
INTEGER :: ls,lt,lsub,ipos,ipow
2885
ls = LEN(string); lt = LEN(target); lsub = LEN(substring)
2888
ALLOCATE(replace_ccc%chars(1:lsub))
2890
replace_ccc%chars(i) = substring(i:i)
2894
ALLOCATE(replace_ccc%chars(1:ls))
2896
replace_ccc%chars(i) = string(i:i)
2901
ALLOCATE(work(1:ls))
2903
work(i) = string(i:i)
2905
IF( PRESENT(back) )THEN
2908
dir_switch = .FALSE.
2910
IF( PRESENT(every) )THEN
2913
rep_search = .FALSE.
2915
IF( dir_switch )THEN ! backwards search
2918
IF( ipos < 1 )EXIT ! search past start of string
2919
! test for occurance of target in string at this position
2920
IF( string(ipos:ipos+lt-1) == target )THEN
2921
! match found allocate space for string with this occurance of
2922
! target replaced by substring
2923
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2924
! copy work into temp replacing this occurance of target by
2926
temp(1:ipos-1) = work(1:ipos-1)
2928
temp(i+ipos-1) = substring(i:i)
2930
temp(ipos+lsub:) = work(ipos+lt:)
2931
work => temp ! make new version of work point at the temp space
2932
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2933
! move search and replacement positions over the effected positions
2938
ELSE ! forward search
2941
IF( ipos > ls-lt+1 )EXIT ! search past end of string
2942
! test for occurance of target in string at this position
2943
IF( string(ipos:ipos+lt-1) == target )THEN
2944
! match found allocate space for string with this occurance of
2945
! target replaced by substring
2946
ALLOCATE(temp(1:SIZE(work)+lsub-lt))
2947
! copy work into temp replacing this occurance of target by
2949
temp(1:ipow-1) = work(1:ipow-1)
2951
temp(i+ipow-1) = substring(i:i)
2953
temp(ipow+lsub:) = work(ipow+lt:)
2954
work => temp ! make new version of work point at the temp space
2955
IF(.NOT.rep_search)EXIT ! exit if only first replacement wanted
2956
! move search and replacement positions over the effected positions
2957
ipos = ipos+lt-1; ipow = ipow+lsub-1
2959
ipos=ipos+1; ipow=ipow+1
2962
replace_ccc%chars => work
2963
ENDFUNCTION replace_ccc
2965
!----- Remove procedures ----------------------------------------------------!
2966
ELEMENTAL FUNCTION remove_s(string,start,finish)
2967
type(VAR_STR) :: remove_s
2968
type(VAR_STR),INTENT(IN) :: string
2969
INTEGER,INTENT(IN),OPTIONAL :: start
2970
INTEGER,INTENT(IN),OPTIONAL :: finish
2971
! returns as result the string produced by the actions
2972
! removes the characters between start and finish from string reducing it in
2973
! size by MAX(0,ABS(finish-start+1))
2974
! if start < 1 or is missing then assumes start=1
2975
! if finish > LEN(string) or is missing then assumes finish=LEN(string)
2976
CHARACTER,DIMENSION(:),POINTER :: arg_str
2979
IF (PRESENT(start)) THEN
2984
IF (PRESENT(finish)) THEN
2989
IF( if < is ) THEN ! zero characters to be removed, string is unchanged
2990
ALLOCATE(arg_str(1:ls))
2991
arg_str = string%chars
2993
ALLOCATE(arg_str(1:ls-if+is-1) )
2994
arg_str(1:is-1) = string%chars(1:is-1)
2995
arg_str(is:) = string%chars(if+1:)
2997
remove_s%chars => arg_str
2998
ENDFUNCTION remove_s
3000
ELEMENTAL FUNCTION remove_c(string,start,finish)
3001
type(VAR_STR) :: remove_c
3002
CHARACTER(LEN=*),INTENT(IN) :: string
3003
INTEGER,INTENT(IN),OPTIONAL :: start
3004
INTEGER,INTENT(IN),OPTIONAL :: finish
3005
! returns as result the string produced by the actions
3006
! removes the characters between start and finish from string reducing it in
3007
! size by MAX(0,ABS(finish-start+1))
3008
! if start < 1 or is missing then assumes start=1
3009
! if finish > LEN(string) or is missing then assumes finish=LEN(string)
3010
CHARACTER,DIMENSION(:),POINTER :: arg_str
3013
IF (PRESENT(start)) THEN
3018
IF (PRESENT(finish)) THEN
3023
IF( if < is ) THEN ! zero characters to be removed, string is unchanged
3024
ALLOCATE(arg_str(1:ls))
3026
arg_str(i) = string(i:i)
3029
ALLOCATE(arg_str(1:ls-if+is-1) )
3031
arg_str(i) = string(i:i)
3034
arg_str(i) = string(i-is+if+1:i-is+if+1)
3037
remove_c%chars => arg_str
3038
ENDFUNCTION remove_c
3040
!----- Extract procedures ---------------------------------------------------!
3041
ELEMENTAL FUNCTION extract_s(string,start,finish)
3042
type(VAR_STR),INTENT(IN) :: string
3043
INTEGER,INTENT(IN),OPTIONAL :: start
3044
INTEGER,INTENT(IN),OPTIONAL :: finish
3045
type(VAR_STR) :: extract_s
3046
! extracts the characters between start and finish from string and
3047
! delivers these as the result of the function, string is unchanged
3048
! if start < 1 or is missing then it is treated as 1
3049
! if finish > LEN(string) or is missing then it is treated as LEN(string)
3051
IF (PRESENT(start)) THEN
3056
IF (PRESENT(finish)) THEN
3057
if = MIN(LEN(string),finish)
3061
ALLOCATE(extract_s%chars(1:if-is+1))
3062
extract_s%chars = string%chars(is:if)
3063
ENDFUNCTION extract_s
3065
ELEMENTAL FUNCTION extract_c(string,start,finish)
3066
CHARACTER(LEN=*),INTENT(IN) :: string
3067
INTEGER,INTENT(IN),OPTIONAL :: start
3068
INTEGER,INTENT(IN),OPTIONAL :: finish
3069
type(VAR_STR) :: extract_c
3070
! extracts the characters between start and finish from character string and
3071
! delivers these as the result of the function, string is unchanged
3072
! if start < 1 or is missing then it is treated as 1
3073
! if finish > LEN(string) or is missing then it is treated as LEN(string)
3075
IF (PRESENT(start)) THEN
3080
IF (PRESENT(finish)) THEN
3081
if = MIN(LEN(string),finish)
3085
ALLOCATE(extract_c%chars(1:if-is+1))
3087
extract_c%chars(i-is+1) = string(i:i)
3089
ENDFUNCTION extract_c
3091
!----- Split procedures ------------------------------------------------------!
3092
ELEMENTAL SUBROUTINE split_s(string,word,set,separator,back)
3093
type(VAR_STR),INTENT(INOUT) :: string
3094
type(VAR_STR),INTENT(OUT) :: word
3095
type(VAR_STR),INTENT(IN) :: set
3096
type(VAR_STR),INTENT(OUT),OPTIONAL :: separator
3097
LOGICAL,INTENT(IN),OPTIONAL :: back
3098
! splits the input string at the first(last) character in set
3099
! returns the leading(trailing) substring in word and the trailing(leading)
3100
! substring in string. The search is done in the forward or backward
3101
! direction depending on back. If separator is present, the actual separator
3102
! character found is returned in separator.
3103
! If no character in set is found string and separator are returned as
3104
! zero length and the whole input string is returned in word.
3105
LOGICAL :: dir_switch
3107
CHARACTER,ALLOCATABLE :: wst(:) ! working copy of string
3111
IF( PRESENT(back) )THEN
3114
dir_switch = .FALSE.
3116
IF(dir_switch)THEN ! backwards search
3118
IF(ANY(wst(tpos) == set%chars))EXIT
3120
IF(ASSOCIATED(word%chars))DEALLOCATE(word%chars)
3121
ALLOCATE(word%chars(ls-tpos))
3122
word%chars = wst(tpos+1:ls)
3123
IF(PRESENT(separator))THEN
3127
separator = wst(tpos)
3130
DEALLOCATE(string%chars)
3131
ALLOCATE(string%chars(tpos-1))
3132
string%chars = wst(1:tpos-1)
3133
ELSE ! forwards search
3135
IF(ANY(wst(tpos) == set%chars))EXIT
3137
IF(ASSOCIATED(word%chars))DEALLOCATE(word%chars)
3138
ALLOCATE(word%chars(tpos-1))
3139
word%chars = wst(1:tpos-1)
3140
IF(PRESENT(separator))THEN
3144
separator = wst(tpos)
3147
DEALLOCATE(string%chars)
3148
ALLOCATE(string%chars(ls-tpos))
3149
string%chars = wst(tpos+1:ls)
3151
ENDSUBROUTINE split_s
3153
ELEMENTAL SUBROUTINE split_c(string,word,set,separator,back)
3154
type(VAR_STR),INTENT(INOUT) :: string
3155
type(VAR_STR),INTENT(OUT) :: word
3156
CHARACTER(LEN=*),INTENT(IN) :: set
3157
type(VAR_STR),INTENT(OUT),OPTIONAL :: separator
3158
LOGICAL,INTENT(IN),OPTIONAL :: back
3159
! splits the input string at the first(last) character in set
3160
! returns the leading(trailing) substring in word and the trailing(leading)
3161
! substring in string. The search is done in the forward or backward
3162
! direction depending on back. If separator is present, the actual separator
3163
! character found is returned in separator.
3164
! If no character in set is found string and separator are returned as
3165
! zero length and the whole input string is returned in word.
3166
LOGICAL :: dir_switch
3167
INTEGER :: ls,tpos,lset
3168
CHARACTER,ALLOCATABLE :: wst(:) ! working copy of string
3169
ls = LEN(string); lset = LEN(set)
3172
IF( PRESENT(back) )THEN
3175
dir_switch = .FALSE.
3177
IF(dir_switch)THEN ! backwards search
3178
BSEARCH:DO tpos = ls,1,-1
3180
IF(wst(tpos) == set(i:i))EXIT BSEARCH
3183
IF(ASSOCIATED(word%chars))DEALLOCATE(word%chars)
3184
ALLOCATE(word%chars(ls-tpos))
3185
word%chars = wst(tpos+1:ls)
3186
IF(PRESENT(separator))THEN
3190
separator = wst(tpos)
3193
DEALLOCATE(string%chars)
3194
ALLOCATE(string%chars(tpos-1))
3195
string%chars = wst(1:tpos-1)
3196
ELSE ! forwards search
3197
FSEARCH:DO tpos =1,ls
3199
IF(wst(tpos) == set(i:i))EXIT FSEARCH
3202
IF(ASSOCIATED(word%chars))DEALLOCATE(word%chars)
3203
ALLOCATE(word%chars(tpos-1))
3204
word%chars = wst(1:tpos-1)
3205
IF(PRESENT(separator))THEN
3209
separator = wst(tpos)
3212
DEALLOCATE(string%chars)
3213
ALLOCATE(string%chars(ls-tpos))
3214
string%chars = wst(tpos+1:ls)
3216
ENDSUBROUTINE split_c
3218
!----- INDEX procedures ------------------------------------------------------!
3219
ELEMENTAL FUNCTION index_ss(string,substring,back)
3220
type(VAR_STR),INTENT(IN) :: string,substring
3221
LOGICAL,INTENT(IN),OPTIONAL :: back
3223
! returns the starting position in string of the substring
3224
! scanning from the front or back depending on the logical argument back
3225
LOGICAL :: dir_switch
3227
ls = LEN(string); lsub = LEN(substring)
3228
IF( PRESENT(back) )THEN
3231
dir_switch = .FALSE.
3233
IF(dir_switch)THEN ! backwards search
3234
DO i = ls-lsub+1,1,-1
3235
IF( ALL(string%chars(i:i+lsub-1) == substring%chars) )THEN
3241
ELSE ! forward search
3243
IF( ALL(string%chars(i:i+lsub-1) == substring%chars) )THEN
3250
ENDFUNCTION index_ss
3252
ELEMENTAL FUNCTION index_sc(string,substring,back)
3253
type(VAR_STR),INTENT(IN) :: string
3254
CHARACTER(LEN=*),INTENT(IN) :: substring
3255
LOGICAL,INTENT(IN),OPTIONAL :: back
3257
! returns the starting position in string of the substring
3258
! scanning from the front or back depending on the logical argument back
3259
LOGICAL :: dir_switch,matched
3261
ls = LEN(string); lsub = LEN(substring)
3262
IF( PRESENT(back) )THEN
3265
dir_switch = .FALSE.
3267
IF (dir_switch) THEN ! backwards search
3268
DO i = ls-lsub+1,1,-1
3271
IF( string%chars(i+j-1) /= substring(j:j) )THEN
3282
ELSE ! forward search
3286
IF( string%chars(i+j-1) /= substring(j:j) )THEN
3298
ENDFUNCTION index_sc
3300
ELEMENTAL FUNCTION index_cs(string,substring,back)
3301
CHARACTER(LEN=*),INTENT(IN) :: string
3302
type(VAR_STR),INTENT(IN) :: substring
3303
LOGICAL,INTENT(IN),OPTIONAL :: back
3305
! returns the starting position in string of the substring
3306
! scanning from the front or back depending on the logical argument back
3307
LOGICAL :: dir_switch,matched
3309
ls = LEN(string); lsub = LEN(substring)
3310
IF( PRESENT(back) )THEN
3313
dir_switch = .FALSE.
3315
IF(dir_switch)THEN ! backwards search
3316
DO i = ls-lsub+1,1,-1
3319
IF( string(i+j-1:i+j-1) /= substring%chars(j) )THEN
3330
ELSE ! forward search
3334
IF( string(i+j-1:i+j-1) /= substring%chars(j) )THEN
3346
ENDFUNCTION index_cs
3348
!----- SCAN procedures ------------------------------------------------------!
3349
ELEMENTAL FUNCTION scan_ss(string,set,back)
3350
type(VAR_STR),INTENT(IN) :: string,set
3351
LOGICAL,INTENT(IN),OPTIONAL :: back
3353
! returns the first position in string occupied by a character from
3354
! the characters in set, scanning is forward or backwards depending on back
3355
LOGICAL :: dir_switch
3358
IF( PRESENT(back) )THEN
3361
dir_switch = .FALSE.
3363
IF(dir_switch)THEN ! backwards search
3365
IF( ANY( set%chars == string%chars(i) ) )THEN
3371
ELSE ! forward search
3373
IF( ANY( set%chars == string%chars(i) ) )THEN
3382
ELEMENTAL FUNCTION scan_sc(string,set,back)
3383
type(VAR_STR),INTENT(IN) :: string
3384
CHARACTER(LEN=*),INTENT(IN) :: set
3385
LOGICAL,INTENT(IN),OPTIONAL :: back
3387
! returns the first position in string occupied by a character from
3388
! the characters in set, scanning is forward or backwards depending on back
3389
LOGICAL :: dir_switch,matched
3392
IF( PRESENT(back) )THEN
3395
dir_switch = .FALSE.
3397
IF(dir_switch)THEN ! backwards search
3401
IF( string%chars(i) == set(j:j) )THEN
3412
ELSE ! forward search
3416
IF( string%chars(i) == set(j:j) )THEN
3430
ELEMENTAL FUNCTION scan_cs(string,set,back)
3431
CHARACTER(LEN=*),INTENT(IN) :: string
3432
type(VAR_STR),INTENT(IN) :: set
3433
LOGICAL,INTENT(IN),OPTIONAL :: back
3435
! returns the first position in character string occupied by a character from
3436
! the characters in set, scanning is forward or backwards depending on back
3437
LOGICAL :: dir_switch,matched
3440
IF( PRESENT(back) )THEN
3443
dir_switch = .FALSE.
3445
IF(dir_switch)THEN ! backwards search
3449
IF( string(i:i) == set%chars(j) )THEN
3460
ELSE ! forward search
3464
IF( string(i:i) == set%chars(j) )THEN
3478
!----- VERIFY procedures ----------------------------------------------------!
3479
ELEMENTAL FUNCTION verify_ss(string,set,back)
3480
type(VAR_STR),INTENT(IN) :: string,set
3481
LOGICAL,INTENT(IN),OPTIONAL :: back
3482
INTEGER :: verify_ss
3483
! returns the first position in string not occupied by a character from
3484
! the characters in set, scanning is forward or backwards depending on back
3485
LOGICAL :: dir_switch
3488
IF( PRESENT(back) )THEN
3491
dir_switch = .FALSE.
3493
IF(dir_switch)THEN ! backwards search
3495
IF( .NOT.(ANY( set%chars == string%chars(i) )) )THEN
3501
ELSE ! forward search
3503
IF( .NOT.(ANY( set%chars == string%chars(i) )) )THEN
3510
ENDFUNCTION verify_ss
3512
ELEMENTAL FUNCTION verify_sc(string,set,back)
3513
type(VAR_STR),INTENT(IN) :: string
3514
CHARACTER(LEN=*),INTENT(IN) :: set
3515
LOGICAL,INTENT(IN),OPTIONAL :: back
3516
INTEGER :: verify_sc
3517
! returns the first position in string not occupied by a character from
3518
! the characters in set, scanning is forward or backwards depending on back
3519
LOGICAL :: dir_switch
3522
IF( PRESENT(back) )THEN
3525
dir_switch = .FALSE.
3527
IF(dir_switch)THEN ! backwards search
3528
back_string_search:DO i = ls,1,-1
3530
IF( string%chars(i) == set(j:j) )CYCLE back_string_search
3531
! cycle string search if string character found in set
3533
! string character not found in set index i is result
3536
ENDDO back_string_search
3537
! each string character found in set
3539
ELSE ! forward search
3540
frwd_string_search:DO i = 1,ls
3542
IF( string%chars(i) == set(j:j) )CYCLE frwd_string_search
3546
ENDDO frwd_string_search
3549
ENDFUNCTION verify_sc
3551
ELEMENTAL FUNCTION verify_cs(string,set,back)
3552
CHARACTER(LEN=*),INTENT(IN) :: string
3553
type(VAR_STR),INTENT(IN) :: set
3554
LOGICAL,INTENT(IN),OPTIONAL :: back
3555
INTEGER :: verify_cs
3556
! returns the first position in icharacter string not occupied by a character
3557
! from the characters in set, scanning is forward or backwards depending on
3559
LOGICAL :: dir_switch
3562
IF( PRESENT(back) )THEN
3565
dir_switch = .FALSE.
3567
IF(dir_switch)THEN ! backwards search
3568
back_string_search:DO i = ls,1,-1
3570
IF( string(i:i) == set%chars(j) )CYCLE back_string_search
3574
ENDDO back_string_search
3576
ELSE ! forward search
3577
frwd_string_search:DO i = 1,ls
3579
IF( string(i:i) == set%chars(j) )CYCLE frwd_string_search
3583
ENDDO frwd_string_search
3586
ENDFUNCTION verify_cs
3588
!----- LEN_TRIM procedure ----------------------------------------------------!
3589
ELEMENTAL FUNCTION len_trim_s(string)
3590
type(VAR_STR),INTENT(IN) :: string
3591
INTEGER :: len_trim_s
3592
! Returns the length of the string without counting trailing blanks
3597
IF (string%chars(i) /= BLANK) THEN
3602
ENDFUNCTION len_trim_s
3604
!----- TRIM procedure -------------------------------------------------------!
3605
ELEMENTAL FUNCTION trim_s(string)
3606
type(VAR_STR),INTENT(IN) :: string
3607
type(VAR_STR) :: trim_s
3608
! Returns the argument string with trailing blanks removed
3613
IF(string%chars(i) /= BLANK) THEN
3618
ALLOCATE(trim_s%chars(1:pos))
3619
trim_s%chars(1:pos) = string%chars(1:pos)
3622
!----- IACHAR procedure ------------------------------------------------------!
3623
ELEMENTAL FUNCTION iachar_s(string)
3624
type(VAR_STR),INTENT(IN) :: string
3626
! returns the position of the character string in the ISO 646
3627
! collating sequence.
3628
! string must be of length one, otherwise result is as for intrinsic IACHAR
3629
iachar_s = IACHAR(CHAR(string))
3630
ENDFUNCTION iachar_s
3632
!----- ICHAR procedure ------------------------------------------------------!
3633
ELEMENTAL FUNCTION ichar_s(string)
3634
type(VAR_STR),INTENT(IN) :: string
3636
! returns the position of character from string in the processor collating
3638
! string must be of length one, otherwise it will behave as the intrinsic
3639
! ICHAR with the equivalent character string
3640
ichar_s = ICHAR(CHAR(string))
3643
!----- ADJUSTL procedure ----------------------------------------------------!
3644
ELEMENTAL FUNCTION adjustl_s(string)
3645
type(VAR_STR),INTENT(IN) :: string
3646
type(VAR_STR) :: adjustl_s
3647
! Returns the string adjusted to the left, removing leading blanks and
3648
! inserting trailing blanks
3652
IF(string%chars(pos) /= blank) EXIT
3654
! pos now holds the position of the first non-blank character
3655
! or ls+1 if all characters are blank
3656
ALLOCATE(adjustl_s%chars(1:ls))
3657
adjustl_s%chars(1:ls-pos+1) = string%chars(pos:ls)
3658
adjustl_s%chars(ls-pos+2:ls) = blank
3659
ENDFUNCTION adjustl_s
3661
!----- ADJUSTR procedure ----------------------------------------------------!
3662
ELEMENTAL FUNCTION adjustr_s(string)
3663
type(VAR_STR),INTENT(IN) :: string
3664
type(VAR_STR) :: adjustr_s
3665
! Returns the string adjusted to the right, removing trailing blanks
3666
! and inserting leading blanks
3670
IF(string%chars(pos) /= blank) EXIT
3672
! pos now holds the position of the last non-blank character
3673
! or zero if all characters are blank
3674
ALLOCATE(adjustr_s%chars(1:ls))
3675
adjustr_s%chars(ls-pos+1:ls) = string%chars(1:pos)
3676
adjustr_s%chars(1:ls-pos) = blank
3677
ENDFUNCTION adjustr_s
3679
ENDMODULE ISO_VAR_STR