1
+ module stdlib_experimental_ascii
2
+
3
+ implicit none
4
+ private
5
+
6
+ ! Character validation functions
7
+ public :: is_alpha, is_alphanum
8
+ public :: is_digit, is_hex_digit, is_octal_digit
9
+ public :: is_control, is_white, is_blank
10
+ public :: is_ascii, is_punctuation
11
+ public :: is_graphical, is_printable
12
+ public :: is_lower, is_upper
13
+
14
+ ! Character conversion functions
15
+ public :: to_lower, to_upper
16
+
17
+ ! All control characters in the ASCII table (see www.asciitable.com).
18
+ character (len= 1 ), public , parameter :: NUL = achar (z' 00' ) ! ! Null
19
+ character (len= 1 ), public , parameter :: SOH = achar (z' 01' ) ! ! Start of heading
20
+ character (len= 1 ), public , parameter :: STX = achar (z' 02' ) ! ! Start of text
21
+ character (len= 1 ), public , parameter :: ETX = achar (z' 03' ) ! ! End of text
22
+ character (len= 1 ), public , parameter :: EOT = achar (z' 04' ) ! ! End of transmission
23
+ character (len= 1 ), public , parameter :: ENQ = achar (z' 05' ) ! ! Enquiry
24
+ character (len= 1 ), public , parameter :: ACK = achar (z' 06' ) ! ! Acknowledge
25
+ character (len= 1 ), public , parameter :: BEL = achar (z' 07' ) ! ! Bell
26
+ character (len= 1 ), public , parameter :: BS = achar (z' 08' ) ! ! Backspace
27
+ character (len= 1 ), public , parameter :: TAB = achar (z' 09' ) ! ! Horizontal tab
28
+ character (len= 1 ), public , parameter :: LF = achar (z' 0A' ) ! ! NL line feed, new line
29
+ character (len= 1 ), public , parameter :: VT = achar (z' 0B' ) ! ! Vertical tab
30
+ character (len= 1 ), public , parameter :: FF = achar (z' 0C' ) ! ! NP form feed, new page
31
+ character (len= 1 ), public , parameter :: CR = achar (z' 0D' ) ! ! Carriage return
32
+ character (len= 1 ), public , parameter :: SO = achar (z' 0E' ) ! ! Shift out
33
+ character (len= 1 ), public , parameter :: SI = achar (z' 0F' ) ! ! Shift in
34
+ character (len= 1 ), public , parameter :: DLE = achar (z' 10' ) ! ! Data link escape
35
+ character (len= 1 ), public , parameter :: DC1 = achar (z' 11' ) ! ! Device control 1
36
+ character (len= 1 ), public , parameter :: DC2 = achar (z' 12' ) ! ! Device control 2
37
+ character (len= 1 ), public , parameter :: DC3 = achar (z' 13' ) ! ! Device control 3
38
+ character (len= 1 ), public , parameter :: DC4 = achar (z' 14' ) ! ! Device control 4
39
+ character (len= 1 ), public , parameter :: NAK = achar (z' 15' ) ! ! Negative acknowledge
40
+ character (len= 1 ), public , parameter :: SYN = achar (z' 16' ) ! ! Synchronous idle
41
+ character (len= 1 ), public , parameter :: ETB = achar (z' 17' ) ! ! End of transmission block
42
+ character (len= 1 ), public , parameter :: CAN = achar (z' 18' ) ! ! Cancel
43
+ character (len= 1 ), public , parameter :: EM = achar (z' 19' ) ! ! End of medium
44
+ character (len= 1 ), public , parameter :: SUB = achar (z' 1A' ) ! ! Substitute
45
+ character (len= 1 ), public , parameter :: ESC = achar (z' 1B' ) ! ! Escape
46
+ character (len= 1 ), public , parameter :: FS = achar (z' 1C' ) ! ! File separator
47
+ character (len= 1 ), public , parameter :: GS = achar (z' 1D' ) ! ! Group separator
48
+ character (len= 1 ), public , parameter :: RS = achar (z' 1E' ) ! ! Record separator
49
+ character (len= 1 ), public , parameter :: US = achar (z' 1F' ) ! ! Unit separator
50
+ character (len= 1 ), public , parameter :: DEL = achar (z' 7F' ) ! ! Delete
51
+
52
+ ! Constant character sequences
53
+ character (len=* ), public , parameter :: fullhex_digits = " 0123456789ABCDEFabcdef" ! ! 0 .. 9A .. Fa .. f
54
+ character (len=* ), public , parameter :: hex_digits = fullhex_digits(1 :16 ) ! ! 0 .. 9A .. F
55
+ character (len=* ), public , parameter :: lowerhex_digits = " 0123456789abcdef" ! ! 0 .. 9a .. f
56
+ character (len=* ), public , parameter :: digits = hex_digits(1 :10 ) ! ! 0 .. 9
57
+ character (len=* ), public , parameter :: octal_digits = digits (1 :8 ) ! ! 0 .. 7
58
+ character (len=* ), public , parameter :: letters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ! ! A .. Za .. z
59
+ character (len=* ), public , parameter :: uppercase = letters(1 :26 ) ! ! A .. Z
60
+ character (len=* ), public , parameter :: lowercase = letters(27 :) ! ! a .. z
61
+ character (len=* ), public , parameter :: whitespace = " " // TAB// VT// CR// LF// FF ! ! ASCII _whitespace
62
+
63
+ contains
64
+
65
+ ! > Checks whether `c` is an ASCII letter (A .. Z, a .. z).
66
+ pure logical function is_alpha(c)
67
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
68
+ is_alpha = (c >= ' A' .and. c <= ' Z' ) .or. (c >= ' a' .and. c <= ' z' )
69
+ end function
70
+
71
+ ! > Checks whether `c` is a letter or a number (0 .. 9, a .. z, A .. Z).
72
+ pure logical function is_alphanum(c)
73
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
74
+ is_alphanum = (c >= ' 0' .and. c <= ' 9' ) .or. (c >= ' a' .and. c <= ' z' ) &
75
+ .or. (c >= ' A' .and. c <= ' Z' )
76
+ end function
77
+
78
+ ! > Checks whether or not `c` is in the ASCII character set -
79
+ ! i.e. in the range 0 .. 0x7F.
80
+ pure logical function is_ascii(c)
81
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
82
+ is_ascii = iachar (c) <= z' 7F'
83
+ end function
84
+
85
+ ! > Checks whether `c` is a control character.
86
+ pure logical function is_control(c)
87
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
88
+ integer :: ic
89
+ ic = iachar (c)
90
+ is_control = ic < z' 20' .or. ic == z' 7F'
91
+ end function
92
+
93
+ ! > Checks whether `c` is a digit (0 .. 9).
94
+ pure logical function is_digit(c)
95
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
96
+ is_digit = (' 0' <= c) .and. (c <= ' 9' )
97
+ end function
98
+
99
+ ! > Checks whether `c` is a digit in base 8 (0 .. 7).
100
+ pure logical function is_octal_digit(c)
101
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
102
+ is_octal_digit = (c >= ' 0' ) .and. (c <= ' 7' );
103
+ end function
104
+
105
+ ! > Checks whether `c` is a digit in base 16 (0 .. 9, A .. F, a .. f).
106
+ pure logical function is_hex_digit(c)
107
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
108
+ is_hex_digit = (c >= ' 0' .and. c <= ' 9' ) .or. (c >= ' a' .and. c <= ' f' ) &
109
+ .or. (c >= ' A' .and. c <= ' F' )
110
+ end function
111
+
112
+ ! > Checks whether or not `c` is a punctuation character. That includes
113
+ ! all ASCII characters which are not control characters, letters,
114
+ ! digits, or whitespace.
115
+ pure logical function is_punctuation(c)
116
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
117
+ integer :: ic
118
+ ic = iachar (c) ! '~' '!'
119
+ is_punctuation = (ic <= z' 7E' ) .and. (ic >= z' 21' ) .and. &
120
+ (.not. is_alphanum(c))
121
+ end function
122
+
123
+ ! > Checks whether or not `c` is a printable character other than the
124
+ ! space character.
125
+ pure logical function is_graphical(c)
126
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
127
+ integer :: ic
128
+ ic = iachar (c) ! '!' '~'
129
+ is_graphical = (z' 21' <= ic) .and. (ic <= z' 7E' )
130
+ end function
131
+
132
+ ! > Checks whether or not `c` is a printable character - including the
133
+ ! space character.
134
+ pure logical function is_printable(c)
135
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
136
+ integer :: ic
137
+ ic = iachar (c) ! '~'
138
+ is_printable = c >= ' ' .and. ic <= z' 7E'
139
+ end function
140
+
141
+ ! > Checks whether `c` is a lowercase ASCII letter (a .. z).
142
+ pure logical function is_lower(c)
143
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
144
+ is_lower = (c >= ' a' ) .and. (c <= ' z' )
145
+ end function
146
+
147
+ ! > Checks whether `c` is an uppercase ASCII letter (A .. Z).
148
+ pure logical function is_upper(c)
149
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
150
+ is_upper = (c >= ' A' ) .and. (c <= ' Z' )
151
+ end function
152
+
153
+ ! > Checks whether or not `c` is a whitespace character. That includes the
154
+ ! space, tab, vertical tab, form feed, carriage return, and linefeed
155
+ ! characters.
156
+ pure logical function is_white(c)
157
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
158
+ integer :: ic
159
+ ic = iachar (c) ! TAB, LF, VT, FF, CR
160
+ is_white = (c == ' ' ) .or. (ic >= z' 09' .and. ic <= z' 0D' );
161
+ end function
162
+
163
+ ! > Checks whether or not `c` is a blank character. That includes the
164
+ ! only the space and tab characters
165
+ pure logical function is_blank(c)
166
+ character (len= 1 ), intent (in ) :: c ! ! The character to test.
167
+ integer :: ic
168
+ ic = iachar (c) ! TAB
169
+ is_blank = (c == ' ' ) .or. (ic == z' 09' );
170
+ end function
171
+
172
+ ! > Returns the corresponding lowercase letter, if `c` is an uppercase
173
+ ! ASCII character, otherwise `c` itself.
174
+ pure function to_lower (c ) result(t)
175
+ character (len= 1 ), intent (in ) :: c ! ! A character.
176
+ character (len= 1 ) :: t
177
+ integer :: diff
178
+ diff = iachar (' A' )- iachar (' a' )
179
+ t = c
180
+ ! if uppercase, make lowercase
181
+ if (is_upper(t)) t = achar (iachar (t) - diff)
182
+ end function
183
+
184
+ ! > Returns the corresponding uppercase letter, if `c` is a lowercase
185
+ ! ASCII character, otherwise `c` itself.
186
+ pure function to_upper (c ) result(t)
187
+ character (len= 1 ), intent (in ) :: c ! ! A character.
188
+ character (len= 1 ) :: t
189
+ integer :: diff
190
+ diff = iachar (' A' )- iachar (' a' )
191
+ t = c
192
+ ! if lowercase, make uppercase
193
+ if (is_lower(t)) t = achar (iachar (t) + diff)
194
+ end function
195
+
196
+ end module
0 commit comments