Rev 7693 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7693 | Rev 7696 | ||
---|---|---|---|
1 | (* |
1 | (* |
2 | BSD 2-Clause License |
2 | BSD 2-Clause License |
3 | 3 | ||
4 | Copyright (c) 2018, 2019, Anton Krotov |
4 | Copyright (c) 2018-2019, Anton Krotov |
5 | All rights reserved. |
5 | All rights reserved. |
6 | *) |
6 | *) |
7 | 7 | ||
8 | MODULE STRINGS; |
8 | MODULE STRINGS; |
9 | 9 | ||
10 | IMPORT UTILS; |
10 | IMPORT UTILS; |
11 | 11 | ||
12 | 12 | ||
13 | PROCEDURE append* (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
13 | PROCEDURE append* (VAR s1: ARRAY OF CHAR; s2: ARRAY OF CHAR); |
14 | VAR |
14 | VAR |
15 | n1, n2, i, j: INTEGER; |
15 | n1, n2, i, j: INTEGER; |
16 | BEGIN |
16 | BEGIN |
17 | n1 := LENGTH(s1); |
17 | n1 := LENGTH(s1); |
18 | n2 := LENGTH(s2); |
18 | n2 := LENGTH(s2); |
19 | 19 | ||
20 | ASSERT(n1 + n2 < LEN(s1)); |
20 | ASSERT(n1 + n2 < LEN(s1)); |
21 | 21 | ||
22 | i := 0; |
22 | i := 0; |
23 | j := n1; |
23 | j := n1; |
24 | WHILE i < n2 DO |
24 | WHILE i < n2 DO |
25 | s1[j] := s2[i]; |
25 | s1[j] := s2[i]; |
26 | INC(i); |
26 | INC(i); |
27 | INC(j) |
27 | INC(j) |
28 | END; |
28 | END; |
29 | 29 | ||
30 | s1[j] := 0X |
30 | s1[j] := 0X |
31 | 31 | ||
32 | END append; |
32 | END append; |
33 | 33 | ||
34 | 34 | ||
35 | PROCEDURE reverse* (VAR s: ARRAY OF CHAR); |
35 | PROCEDURE reverse* (VAR s: ARRAY OF CHAR); |
36 | VAR |
36 | VAR |
37 | i, j: INTEGER; |
37 | i, j: INTEGER; |
38 | a, b: CHAR; |
38 | a, b: CHAR; |
39 | 39 | ||
40 | BEGIN |
40 | BEGIN |
41 | 41 | ||
42 | i := 0; |
42 | i := 0; |
43 | j := LENGTH(s) - 1; |
43 | j := LENGTH(s) - 1; |
44 | 44 | ||
45 | WHILE i < j DO |
45 | WHILE i < j DO |
46 | a := s[i]; |
46 | a := s[i]; |
47 | b := s[j]; |
47 | b := s[j]; |
48 | s[i] := b; |
48 | s[i] := b; |
49 | s[j] := a; |
49 | s[j] := a; |
50 | INC(i); |
50 | INC(i); |
51 | DEC(j) |
51 | DEC(j) |
52 | END |
52 | END |
53 | END reverse; |
53 | END reverse; |
54 | 54 | ||
55 | 55 | ||
56 | PROCEDURE IntToStr* (x: INTEGER; VAR str: ARRAY OF CHAR); |
56 | PROCEDURE IntToStr* (x: INTEGER; VAR str: ARRAY OF CHAR); |
57 | VAR |
57 | VAR |
58 | i, a: INTEGER; |
58 | i, a: INTEGER; |
59 | minus: BOOLEAN; |
59 | minus: BOOLEAN; |
60 | 60 | ||
61 | BEGIN |
61 | BEGIN |
62 | IF x = UTILS.minint THEN |
62 | IF x = UTILS.minint THEN |
63 | IF UTILS.bit_depth = 32 THEN |
63 | IF UTILS.bit_depth = 32 THEN |
64 | COPY("-2147483648", str) |
64 | COPY("-2147483648", str) |
65 | ELSIF UTILS.bit_depth = 64 THEN |
65 | ELSIF UTILS.bit_depth = 64 THEN |
66 | COPY("-9223372036854775808", str) |
66 | COPY("-9223372036854775808", str) |
67 | END |
67 | END |
68 | 68 | ||
69 | ELSE |
69 | ELSE |
70 | 70 | ||
71 | minus := x < 0; |
71 | minus := x < 0; |
72 | IF minus THEN |
72 | IF minus THEN |
73 | x := -x |
73 | x := -x |
74 | END; |
74 | END; |
75 | i := 0; |
75 | i := 0; |
76 | a := 0; |
76 | a := 0; |
77 | REPEAT |
77 | REPEAT |
78 | str[i] := CHR(x MOD 10 + ORD("0")); |
78 | str[i] := CHR(x MOD 10 + ORD("0")); |
79 | x := x DIV 10; |
79 | x := x DIV 10; |
80 | INC(i) |
80 | INC(i) |
81 | UNTIL x = 0; |
81 | UNTIL x = 0; |
82 | 82 | ||
83 | IF minus THEN |
83 | IF minus THEN |
84 | str[i] := "-"; |
84 | str[i] := "-"; |
85 | INC(i) |
85 | INC(i) |
86 | END; |
86 | END; |
87 | 87 | ||
88 | str[i] := 0X; |
88 | str[i] := 0X; |
89 | reverse(str) |
89 | reverse(str) |
90 | 90 | ||
91 | END |
91 | END |
92 | END IntToStr; |
92 | END IntToStr; |
93 | 93 | ||
94 | 94 | ||
95 | PROCEDURE hexdgt (n: BYTE): BYTE; |
95 | PROCEDURE hexdgt (n: BYTE): BYTE; |
96 | BEGIN |
96 | BEGIN |
97 | IF n < 10 THEN |
97 | IF n < 10 THEN |
98 | n := n + ORD("0") |
98 | n := n + ORD("0") |
99 | ELSE |
99 | ELSE |
100 | n := n - 10 + ORD("A") |
100 | n := n - 10 + ORD("A") |
101 | END |
101 | END |
102 | 102 | ||
103 | RETURN n |
103 | RETURN n |
104 | END hexdgt; |
104 | END hexdgt; |
105 | 105 | ||
106 | 106 | ||
107 | PROCEDURE IntToHex* (x: INTEGER; VAR str: ARRAY OF CHAR; n: INTEGER); |
107 | PROCEDURE IntToHex* (x: INTEGER; VAR str: ARRAY OF CHAR; n: INTEGER); |
108 | BEGIN |
108 | BEGIN |
109 | str[n] := 0X; |
109 | str[n] := 0X; |
110 | WHILE n > 0 DO |
110 | WHILE n > 0 DO |
111 | str[n - 1] := CHR(hexdgt(x MOD 16)); |
111 | str[n - 1] := CHR(hexdgt(x MOD 16)); |
112 | x := x DIV 16; |
112 | x := x DIV 16; |
113 | DEC(n) |
113 | DEC(n) |
114 | END |
114 | END |
115 | END IntToHex; |
115 | END IntToHex; |
116 | 116 | ||
117 | 117 | ||
118 | PROCEDURE copy* (src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR; spos, dpos, count: INTEGER); |
118 | PROCEDURE copy* (src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR; spos, dpos, count: INTEGER); |
119 | BEGIN |
119 | BEGIN |
120 | WHILE count > 0 DO |
120 | WHILE count > 0 DO |
121 | dst[dpos] := src[spos]; |
121 | dst[dpos] := src[spos]; |
122 | INC(spos); |
122 | INC(spos); |
123 | INC(dpos); |
123 | INC(dpos); |
124 | DEC(count) |
124 | DEC(count) |
125 | END |
125 | END |
126 | END copy; |
126 | END copy; |
127 | 127 | ||
128 | 128 | ||
129 | PROCEDURE search* (s: ARRAY OF CHAR; VAR pos: INTEGER; c: CHAR; forward: BOOLEAN); |
129 | PROCEDURE search* (s: ARRAY OF CHAR; VAR pos: INTEGER; c: CHAR; forward: BOOLEAN); |
130 | VAR |
130 | VAR |
131 | length: INTEGER; |
131 | length: INTEGER; |
132 | 132 | ||
133 | BEGIN |
133 | BEGIN |
134 | length := LENGTH(s); |
134 | length := LENGTH(s); |
135 | 135 | ||
136 | IF (0 <= pos) & (pos < length) THEN |
136 | IF (0 <= pos) & (pos < length) THEN |
137 | IF forward THEN |
137 | IF forward THEN |
138 | WHILE (pos < length) & (s[pos] # c) DO |
138 | WHILE (pos < length) & (s[pos] # c) DO |
139 | INC(pos) |
139 | INC(pos) |
140 | END; |
140 | END; |
141 | IF pos = length THEN |
141 | IF pos = length THEN |
142 | pos := -1 |
142 | pos := -1 |
143 | END |
143 | END |
144 | ELSE |
144 | ELSE |
145 | WHILE (pos >= 0) & (s[pos] # c) DO |
145 | WHILE (pos >= 0) & (s[pos] # c) DO |
146 | DEC(pos) |
146 | DEC(pos) |
147 | END |
147 | END |
148 | END |
148 | END |
149 | ELSE |
149 | ELSE |
150 | pos := -1 |
150 | pos := -1 |
151 | END |
151 | END |
152 | END search; |
152 | END search; |
153 | 153 | ||
154 | 154 | ||
155 | PROCEDURE letter* (c: CHAR): BOOLEAN; |
155 | PROCEDURE letter* (c: CHAR): BOOLEAN; |
156 | RETURN ("a" <= c) & (c <= "z") OR ("A" <= c) & (c <= "Z") OR (c = "_") |
156 | RETURN ("a" <= c) & (c <= "z") OR ("A" <= c) & (c <= "Z") OR (c = "_") |
157 | END letter; |
157 | END letter; |
158 | 158 | ||
159 | 159 | ||
160 | PROCEDURE digit* (c: CHAR): BOOLEAN; |
160 | PROCEDURE digit* (c: CHAR): BOOLEAN; |
161 | RETURN ("0" <= c) & (c <= "9") |
161 | RETURN ("0" <= c) & (c <= "9") |
162 | END digit; |
162 | END digit; |
163 | 163 | ||
164 | 164 | ||
165 | PROCEDURE hexdigit* (c: CHAR): BOOLEAN; |
165 | PROCEDURE hexdigit* (c: CHAR): BOOLEAN; |
166 | RETURN ("0" <= c) & (c <= "9") OR ("A" <= c) & (c <= "F") |
166 | RETURN ("0" <= c) & (c <= "9") OR ("A" <= c) & (c <= "F") |
167 | END hexdigit; |
167 | END hexdigit; |
168 | 168 | ||
169 | 169 | ||
170 | PROCEDURE space* (c: CHAR): BOOLEAN; |
170 | PROCEDURE space* (c: CHAR): BOOLEAN; |
171 | RETURN (0X < c) & (c <= 20X) |
171 | RETURN (0X < c) & (c <= 20X) |
172 | END space; |
172 | END space; |
173 | 173 | ||
174 | 174 | ||
175 | PROCEDURE StrToInt* (str: ARRAY OF CHAR; VAR x: INTEGER): BOOLEAN; |
175 | PROCEDURE StrToInt* (str: ARRAY OF CHAR; VAR x: INTEGER): BOOLEAN; |
176 | VAR |
176 | VAR |
177 | i, k: INTEGER; |
177 | i, k: INTEGER; |
178 | res: BOOLEAN; |
178 | res: BOOLEAN; |
179 | 179 | ||
180 | BEGIN |
180 | BEGIN |
181 | res := TRUE; |
181 | res := TRUE; |
182 | i := 0; |
182 | i := 0; |
183 | x := 0; |
183 | x := 0; |
184 | k := LENGTH(str); |
184 | k := LENGTH(str); |
185 | WHILE i < k DO |
185 | WHILE i < k DO |
186 | IF digit(str[i]) THEN |
186 | IF digit(str[i]) THEN |
187 | x := x * 10 + ORD(str[i]) - ORD("0") |
187 | x := x * 10 + ORD(str[i]) - ORD("0") |
188 | ELSE |
188 | ELSE |
189 | i := k; |
189 | i := k; |
190 | res := FALSE |
190 | res := FALSE |
191 | END; |
191 | END; |
192 | INC(i) |
192 | INC(i) |
193 | END |
193 | END |
194 | 194 | ||
195 | RETURN res |
195 | RETURN res |
196 | END StrToInt; |
196 | END StrToInt; |
197 | 197 | ||
198 | 198 | ||
199 | PROCEDURE CheckVer (str: ARRAY OF CHAR): BOOLEAN; |
199 | PROCEDURE CheckVer (str: ARRAY OF CHAR): BOOLEAN; |
200 | VAR |
200 | VAR |
201 | i, k: INTEGER; |
201 | i, k: INTEGER; |
202 | res: BOOLEAN; |
202 | res: BOOLEAN; |
203 | 203 | ||
204 | BEGIN |
204 | BEGIN |
205 | k := LENGTH(str); |
205 | k := LENGTH(str); |
206 | res := k < LEN(str); |
206 | res := k < LEN(str); |
207 | 207 | ||
208 | IF res & digit(str[0]) THEN |
208 | IF res & digit(str[0]) THEN |
209 | i := 0; |
209 | i := 0; |
210 | WHILE (i < k) & digit(str[i]) DO |
210 | WHILE (i < k) & digit(str[i]) DO |
211 | INC(i) |
211 | INC(i) |
212 | END; |
212 | END; |
213 | IF (i < k) & (str[i] = ".") THEN |
213 | IF (i < k) & (str[i] = ".") THEN |
214 | INC(i); |
214 | INC(i); |
215 | IF i < k THEN |
215 | IF i < k THEN |
216 | WHILE (i < k) & digit(str[i]) DO |
216 | WHILE (i < k) & digit(str[i]) DO |
217 | INC(i) |
217 | INC(i) |
218 | END |
218 | END |
219 | ELSE |
219 | ELSE |
220 | res := FALSE |
220 | res := FALSE |
221 | END |
221 | END |
222 | ELSE |
222 | ELSE |
223 | res := FALSE |
223 | res := FALSE |
224 | END; |
224 | END; |
225 | 225 | ||
226 | res := res & (i = k) |
226 | res := res & (i = k) |
227 | ELSE |
227 | ELSE |
228 | res := FALSE |
228 | res := FALSE |
229 | END |
229 | END |
230 | 230 | ||
231 | RETURN res |
231 | RETURN res |
232 | END CheckVer; |
232 | END CheckVer; |
233 | 233 | ||
234 | 234 | ||
235 | PROCEDURE StrToVer* (str: ARRAY OF CHAR; VAR major, minor: INTEGER): BOOLEAN; |
235 | PROCEDURE StrToVer* (str: ARRAY OF CHAR; VAR major, minor: INTEGER): BOOLEAN; |
236 | VAR |
236 | VAR |
237 | i: INTEGER; |
237 | i: INTEGER; |
238 | res: BOOLEAN; |
238 | res: BOOLEAN; |
239 | 239 | ||
240 | BEGIN |
240 | BEGIN |
241 | res := CheckVer(str); |
241 | res := CheckVer(str); |
242 | 242 | ||
243 | IF res THEN |
243 | IF res THEN |
244 | i := 0; |
244 | i := 0; |
245 | minor := 0; |
245 | minor := 0; |
246 | major := 0; |
246 | major := 0; |
247 | WHILE digit(str[i]) DO |
247 | WHILE digit(str[i]) DO |
248 | major := major * 10 + ORD(str[i]) - ORD("0"); |
248 | major := major * 10 + ORD(str[i]) - ORD("0"); |
249 | INC(i) |
249 | INC(i) |
250 | END; |
250 | END; |
251 | INC(i); |
251 | INC(i); |
252 | WHILE digit(str[i]) DO |
252 | WHILE digit(str[i]) DO |
253 | minor := minor * 10 + ORD(str[i]) - ORD("0"); |
253 | minor := minor * 10 + ORD(str[i]) - ORD("0"); |
254 | INC(i) |
254 | INC(i) |
255 | END |
255 | END |
256 | END |
256 | END |
257 | 257 | ||
258 | RETURN res |
258 | RETURN res |
259 | END StrToVer; |
259 | END StrToVer; |
260 | 260 | ||
261 | 261 | ||
262 | PROCEDURE Utf8To16* (src: ARRAY OF CHAR; VAR dst: ARRAY OF WCHAR): INTEGER; |
262 | PROCEDURE Utf8To16* (src: ARRAY OF CHAR; VAR dst: ARRAY OF WCHAR): INTEGER; |
263 | VAR |
263 | VAR |
264 | i, j, u, srclen, dstlen: INTEGER; |
264 | i, j, u, srclen, dstlen: INTEGER; |
265 | c: CHAR; |
265 | c: CHAR; |
266 | 266 | ||
267 | BEGIN |
267 | BEGIN |
268 | srclen := LEN(src); |
268 | srclen := LEN(src); |
269 | dstlen := LEN(dst); |
269 | dstlen := LEN(dst); |
270 | i := 0; |
270 | i := 0; |
271 | j := 0; |
271 | j := 0; |
272 | WHILE (i < srclen) & (j < dstlen) & (src[i] # 0X) DO |
272 | WHILE (i < srclen) & (j < dstlen) & (src[i] # 0X) DO |
273 | c := src[i]; |
273 | c := src[i]; |
274 | CASE c OF |
274 | CASE c OF |
275 | |00X..7FX: |
275 | |00X..7FX: |
276 | u := ORD(c) |
276 | u := ORD(c) |
277 | 277 | ||
278 | |0C1X..0DFX: |
278 | |0C1X..0DFX: |
279 | u := LSL(ORD(c) - 0C0H, 6); |
279 | u := LSL(ORD(c) - 0C0H, 6); |
280 | IF i + 1 < srclen THEN |
280 | IF i + 1 < srclen THEN |
281 | INC(i); |
281 | INC(i); |
282 | INC(u, ORD(BITS(ORD(src[i])) * {0..5})) |
282 | INC(u, ORD(BITS(ORD(src[i])) * {0..5})) |
283 | END |
283 | END |
284 | 284 | ||
285 | |0E1X..0EFX: |
285 | |0E1X..0EFX: |
286 | u := LSL(ORD(c) - 0E0H, 12); |
286 | u := LSL(ORD(c) - 0E0H, 12); |
287 | IF i + 1 < srclen THEN |
287 | IF i + 1 < srclen THEN |
288 | INC(i); |
288 | INC(i); |
289 | INC(u, ORD(BITS(ORD(src[i])) * {0..5}) * 64) |
289 | INC(u, ORD(BITS(ORD(src[i])) * {0..5}) * 64) |
290 | END; |
290 | END; |
291 | IF i + 1 < srclen THEN |
291 | IF i + 1 < srclen THEN |
292 | INC(i); |
292 | INC(i); |
293 | INC(u, ORD(BITS(ORD(src[i])) * {0..5})) |
293 | INC(u, ORD(BITS(ORD(src[i])) * {0..5})) |
294 | END |
294 | END |
295 | (* |
295 | (* |
296 | |0F1X..0F7X: |
296 | |0F1X..0F7X: |
297 | |0F9X..0FBX: |
297 | |0F9X..0FBX: |
298 | |0FDX: |
298 | |0FDX: |
299 | *) |
299 | *) |
300 | ELSE |
300 | ELSE |
301 | END; |
301 | END; |
302 | INC(i); |
302 | INC(i); |
303 | dst[j] := WCHR(u); |
303 | dst[j] := WCHR(u); |
304 | INC(j) |
304 | INC(j) |
305 | END; |
305 | END; |
306 | IF j < dstlen THEN |
306 | IF j < dstlen THEN |
307 | dst[j] := WCHR(0) |
307 | dst[j] := WCHR(0) |
308 | END |
308 | END |
309 | 309 | ||
310 | RETURN j |
310 | RETURN j |
311 | END Utf8To16; |
311 | END Utf8To16; |
312 | 312 | ||
313 | 313 | ||
314 | END STRINGS.>>>>>>>>>>>>=>>=>=>=>=>=>=>=>=>=>=>>>=>>>>>> |
314 | END STRINGS.>>>>>>>>>>>>=>>=>=>=>=>=>=>=>=>=>=>>>=>>>>>> |