Skip to content

Commit 4725345

Browse files
committed
Implement strip and chomp as supplement to trim
1 parent bc37bcc commit 4725345

8 files changed

+317
-3
lines changed

doc/specs/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This is and index/directory of the specifications (specs) for each new module/fe
2222
- [stats](./stdlib_stats.html) - Descriptive Statistics
2323
- [stats_distribution_PRNG](./stdlib_stats_distribution_PRNG.html) - Probability Distributions random number generator
2424
- [string\_type](./stdlib_string_type.html) - Basic string support
25+
- [strings](./stdlib_strings.html) - String handling and manipulation routines
2526

2627
## Missing specs
2728

doc/specs/stdlib_strings.md

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
title: string handling
3+
---
4+
5+
# The `stdlib_strings` module
6+
7+
[TOC]
8+
9+
## Introduction
10+
11+
The `stdlib_strings` module provides basic string handling and manipulation routines.
12+
13+
14+
## Procedures and methods provided
15+
16+
17+
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
18+
### `strip`
19+
20+
#### Description
21+
22+
Remove leading and trailing whitespace characters.
23+
24+
#### Syntax
25+
26+
`string = [[stdlib_strings(module):strip(interface)]] (string)`
27+
28+
#### Status
29+
30+
Experimental
31+
32+
#### Class
33+
34+
Pure function.
35+
36+
#### Argument
37+
38+
- `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]].
39+
This argument is intent(in).
40+
41+
#### Result value
42+
43+
The result is of the same type as `string`.
44+
45+
#### Example
46+
47+
```fortran
48+
program demo
49+
use stdlib_ascii, only : TAB, VT, NUL, LF, CR, FF
50+
use stdlib_strings, only : strip
51+
implicit none
52+
print'(a)', strip(" hello ") ! "hello"
53+
print'(a)', strip(TAB//"goodbye"//CR//LF) ! "goodbye"
54+
print'(a)', strip(" "//TAB//LF//VT//FF//CR) ! ""
55+
print'(a)', strip(" ! ")//"!" ! "!!"
56+
print'(a)', strip("Hello") ! "Hello"
57+
end program demo
58+
```
59+
60+
61+
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
62+
### `chomp`
63+
64+
#### Description
65+
66+
Remove trailing characters in *set* from *string*.
67+
If no character *set* is provided trailing whitespace is removed.
68+
69+
#### Syntax
70+
71+
`string = [[stdlib_strings(module):chomp(interface)]] (string[, set])`
72+
73+
#### Status
74+
75+
Experimental
76+
77+
#### Class
78+
79+
Pure function.
80+
81+
#### Argument
82+
83+
- `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]].
84+
This argument is intent(in).
85+
- `set`: Character scalar or [[stdlib_string_type(module):string_type(type)]].
86+
This argument is intent(in).
87+
88+
#### Result value
89+
90+
The result is of the same type as `string`.
91+
92+
#### Example
93+
94+
```fortran
95+
program demo
96+
use stdlib_ascii, only : TAB, VT, NUL, LF, CR, FF
97+
use stdlib_strings, only : chomp
98+
implicit none
99+
print'(a)', chomp(" hello ") ! " hello"
100+
print'(a)', chomp(TAB//"goodbye"//CR//LF) ! "\tgoodbye"
101+
print'(a)', chomp(" "//TAB//LF//VT//FF//CR) ! ""
102+
print'(a)', chomp(" ! ")//"!" ! " !!"
103+
print'(a)', chomp("Hello") ! "Hello"
104+
print'(a)', chomp("hello", set="lo") ! "he"
105+
end program demo
106+
```

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ set(SRC
4242
stdlib_kinds.f90
4343
stdlib_logger.f90
4444
stdlib_string_type.f90
45+
stdlib_strings.f90
4546
stdlib_system.F90
4647
${outFiles}
4748
)

src/Makefile.manual

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SRC = f18estop.f90 \
2525
stdlib_error.f90 \
2626
stdlib_kinds.f90 \
2727
stdlib_logger.f90 \
28+
stdlib_strings.f90 \
2829
stdlib_string_type.f90 \
2930
$(SRCGEN)
3031

@@ -109,4 +110,5 @@ stdlib_stats_var.o: \
109110
stdlib_stats_distribution_PRNG.o: \
110111
stdlib_kinds.o \
111112
stdlib_error.o
112-
stdlib_string_type.o: stdlib_ascii.o
113+
stdlib_string_type.o: stdlib_ascii.o
114+
stdlib_strings.o: stdlib_ascii.o stdlib_string_type.o

src/stdlib_strings.f90

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
! SPDX-Identifier: MIT
2+
3+
!> This module implements basic string handling routines.
4+
!>
5+
!> The specification of this module is available [here](../page/specs/stdlib_strings.html).
6+
module stdlib_strings
7+
use stdlib_ascii, only : whitespace
8+
use stdlib_string_type, only : string_type, char
9+
implicit none
10+
private
11+
12+
public :: strip, chomp
13+
14+
15+
!> Remove leading and trailing whitespace characters.
16+
!>
17+
!> Version: experimental
18+
interface strip
19+
module procedure :: strip_string
20+
module procedure :: strip_char
21+
end interface strip
22+
23+
!> Remove trailing characters in set from string.
24+
!> If no character set is provided trailing whitespace is removed.
25+
!>
26+
!> Version: experimental
27+
interface chomp
28+
module procedure :: chomp_string
29+
module procedure :: chomp_char
30+
module procedure :: chomp_string_string
31+
module procedure :: chomp_char_string
32+
module procedure :: chomp_string_char
33+
module procedure :: chomp_char_char
34+
end interface chomp
35+
36+
37+
contains
38+
39+
40+
!> Remove leading and trailing whitespace characters.
41+
pure function strip_string(string) result(stripped_string)
42+
! Avoid polluting the module scope and use the assignment only in this scope
43+
use stdlib_string_type, only : assignment(=)
44+
type(string_type), intent(in) :: string
45+
type(string_type) :: stripped_string
46+
47+
stripped_string = strip(char(string))
48+
end function strip_string
49+
50+
!> Remove leading and trailing whitespace characters.
51+
pure function strip_char(string) result(stripped_string)
52+
character(len=*), intent(in) :: string
53+
character(len=:), allocatable :: stripped_string
54+
integer :: first, last
55+
56+
first = verify(string, whitespace)
57+
if (first == 0) then
58+
stripped_string = ""
59+
else
60+
last = verify(string, whitespace, back=.true.)
61+
stripped_string = string(first:last)
62+
end if
63+
64+
end function strip_char
65+
66+
67+
!> Remove trailing characters in set from string.
68+
!> Default character set variant where trailing whitespace is removed.
69+
pure function chomp_string(string) result(chomped_string)
70+
! Avoid polluting the module scope and use the assignment only in this scope
71+
use stdlib_string_type, only : assignment(=)
72+
type(string_type), intent(in) :: string
73+
type(string_type) :: chomped_string
74+
75+
chomped_string = chomp(char(string), whitespace)
76+
end function chomp_string
77+
78+
!> Remove trailing characters in set from string.
79+
!> Default character set variant where trailing whitespace is removed.
80+
pure function chomp_char(string) result(chomped_string)
81+
character(len=*), intent(in) :: string
82+
character(len=:), allocatable :: chomped_string
83+
84+
chomped_string = chomp(string, whitespace)
85+
end function chomp_char
86+
87+
!> Remove trailing characters in set from string.
88+
pure function chomp_string_string(string, set) result(chomped_string)
89+
! Avoid polluting the module scope and use the assignment only in this scope
90+
use stdlib_string_type, only : assignment(=)
91+
type(string_type), intent(in) :: string
92+
type(string_type), intent(in) :: set
93+
type(string_type) :: chomped_string
94+
95+
chomped_string = chomp(char(string), char(set))
96+
end function chomp_string_string
97+
98+
!> Remove trailing characters in set from string.
99+
pure function chomp_string_char(string, set) result(chomped_string)
100+
! Avoid polluting the module scope and use the assignment only in this scope
101+
use stdlib_string_type, only : assignment(=)
102+
type(string_type), intent(in) :: string
103+
character(len=*), intent(in) :: set
104+
type(string_type) :: chomped_string
105+
106+
chomped_string = chomp(char(string), set)
107+
end function chomp_string_char
108+
109+
!> Remove trailing characters in set from string.
110+
pure function chomp_char_string(string, set) result(chomped_string)
111+
character(len=*), intent(in) :: string
112+
type(string_type), intent(in) :: set
113+
character(len=:), allocatable :: chomped_string
114+
115+
chomped_string = chomp(string, char(set))
116+
end function chomp_char_string
117+
118+
!> Remove trailing characters in set from string.
119+
pure function chomp_char_char(string, set) result(chomped_string)
120+
character(len=*), intent(in) :: string
121+
character(len=*), intent(in) :: set
122+
character(len=:), allocatable :: chomped_string
123+
integer :: last
124+
125+
last = verify(string, set, back=.true.)
126+
chomped_string = string(1:last)
127+
128+
end function chomp_char_char
129+
130+
131+
end module stdlib_strings

src/tests/string/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ ADDTEST(string_operator)
33
ADDTEST(string_intrinsic)
44
ADDTEST(string_derivedtype_io)
55
ADDTEST(string_functions)
6-
6+
ADDTEST(string_trim)

src/tests/string/Makefile.manual

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ PROGS_SRC = test_string_assignment.f90 \
22
test_string_derivedtype_io.f90 \
33
test_string_functions.f90 \
44
test_string_intrinsic.f90 \
5-
test_string_operator.f90
5+
test_string_operator.f90 \
6+
test_string_trim.f90
67

78

89
include ../Makefile.manual.test.mk

src/tests/string/test_string_trim.f90

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
! SPDX-Identifier: MIT
2+
module test_trim
3+
use stdlib_ascii, only : TAB, VT, NUL, LF, CR, FF
4+
use stdlib_error, only : check
5+
use stdlib_strings, only : strip, chomp
6+
use stdlib_string_type, only : string_type, operator(==), operator(//)
7+
implicit none
8+
9+
contains
10+
11+
subroutine test_strip_char
12+
call check(strip(" hello ") == "hello")
13+
call check(strip(TAB//"goodbye"//CR//LF) == "goodbye")
14+
call check(strip(NUL//TAB//LF//VT//FF//CR) == NUL)
15+
call check(strip(" "//TAB//LF//VT//FF//CR) == "")
16+
call check(strip(" ! ")//"!" == "!!")
17+
call check(strip("Hello") == "Hello")
18+
end subroutine test_strip_char
19+
20+
subroutine test_strip_string
21+
call check(strip(string_type(" hello ")) == "hello")
22+
call check(strip(string_type(TAB//"goodbye"//CR//LF)) == "goodbye")
23+
call check(strip(string_type(NUL//TAB//LF//VT//FF//CR)) == NUL)
24+
call check(strip(string_type(" "//TAB//LF//VT//FF//CR)) == "")
25+
call check(strip(string_type(" ! "))//"!" == "!!")
26+
call check(strip(string_type("Hello")) == "Hello")
27+
end subroutine test_strip_string
28+
29+
subroutine test_chomp_char
30+
call check(chomp("hello") == "hello")
31+
call check(chomp("hello"//LF) == "hello")
32+
call check(chomp("hello"//CR//LF) == "hello")
33+
call check(chomp("hello"//LF//CR) == "hello")
34+
call check(chomp("hello"//CR) == "hello")
35+
call check(chomp("hello "//LF//" there") == "hello "//LF//" there")
36+
call check(chomp("hello", set="lo") == "he")
37+
call check(chomp("hello"//CR//LF//CR//LF) == "hello")
38+
call check(chomp("hello"//CR//LF//CR//CR//LF) == "hello")
39+
call check(chomp(NUL//TAB//LF//VT//FF//CR) == NUL)
40+
call check(chomp(" "//TAB//LF//VT//FF//CR) == "")
41+
call check(chomp(" ! ")//"!" == " !!")
42+
end subroutine test_chomp_char
43+
44+
subroutine test_chomp_string
45+
call check(chomp(string_type("hello")) == "hello")
46+
call check(chomp(string_type("hello"//LF)) == "hello")
47+
call check(chomp(string_type("hello"//CR//LF)) == "hello")
48+
call check(chomp(string_type("hello"//LF//CR)) == "hello")
49+
call check(chomp(string_type("hello"//CR)) == "hello")
50+
call check(chomp(string_type("hello "//LF//" there")) == "hello "//LF//" there")
51+
call check(chomp(string_type("hello"), set="lo") == "he")
52+
call check(chomp("hello", set=string_type("lo")) == "he")
53+
call check(chomp(string_type("hello"), set=string_type("lo")) == "he")
54+
call check(chomp(string_type("hello"//CR//LF//CR//LF)) == "hello")
55+
call check(chomp(string_type("hello"//CR//LF//CR//CR//LF)) == "hello")
56+
call check(chomp(string_type(NUL//TAB//LF//VT//FF//CR)) == NUL)
57+
call check(chomp(string_type(" "//TAB//LF//VT//FF//CR)) == "")
58+
call check(chomp(string_type(" ! "))//"!" == " !!")
59+
end subroutine test_chomp_string
60+
61+
end module test_trim
62+
63+
program tester
64+
use test_trim
65+
implicit none
66+
67+
call test_strip_char
68+
call test_strip_string
69+
call test_chomp_char
70+
call test_chomp_string
71+
72+
end program tester

0 commit comments

Comments
 (0)