]>
Commit | Line | Data |
---|---|---|
7401123f GM |
1 | /* do not edit automatically generated by mc from StrLib. */ |
2 | /* StrLib.mod provides string manipulation procedures. | |
3 | ||
4 | Copyright (C) 2001-2021 Free Software Foundation, Inc. | |
5 | Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. | |
6 | ||
7 | This file is part of GNU Modula-2. | |
8 | ||
9 | GNU Modula-2 is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 3, or (at your option) | |
12 | any later version. | |
13 | ||
14 | GNU Modula-2 is distributed in the hope that it will be useful, but | |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | General Public License for more details. | |
18 | ||
19 | Under Section 7 of GPL version 3, you are granted additional | |
20 | permissions described in the GCC Runtime Library Exception, version | |
21 | 3.1, as published by the Free Software Foundation. | |
22 | ||
23 | You should have received a copy of the GNU General Public License and | |
24 | a copy of the GCC Runtime Library Exception along with this program; | |
25 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
26 | <http://www.gnu.org/licenses/>. */ | |
27 | ||
28 | #include "config.h" | |
29 | #include "system.h" | |
30 | # if !defined (PROC_D) | |
31 | # define PROC_D | |
32 | typedef void (*PROC_t) (void); | |
33 | typedef struct { PROC_t proc; } PROC; | |
34 | # endif | |
35 | ||
36 | # if !defined (TRUE) | |
37 | # define TRUE (1==1) | |
38 | # endif | |
39 | ||
40 | # if !defined (FALSE) | |
41 | # define FALSE (1==0) | |
42 | # endif | |
43 | ||
44 | #define _StrLib_H | |
45 | #define _StrLib_C | |
46 | ||
47 | # include "GASCII.h" | |
48 | ||
49 | ||
50 | /* | |
51 | StrConCat - combines a and b into c. | |
52 | */ | |
53 | ||
51bc4b81 | 54 | extern "C" void StrLib_StrConCat (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high, char *c, unsigned int _c_high); |
7401123f GM |
55 | |
56 | /* | |
57 | StrLess - returns TRUE if string, a, alphabetically occurs before | |
58 | string, b. | |
59 | */ | |
60 | ||
51bc4b81 GM |
61 | extern "C" unsigned int StrLib_StrLess (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high); |
62 | extern "C" unsigned int StrLib_StrEqual (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high); | |
63 | extern "C" unsigned int StrLib_StrLen (const char *a_, unsigned int _a_high); | |
c9fba1bc GM |
64 | |
65 | /* | |
66 | StrCopy - copy string src into string dest providing dest is large enough. | |
67 | If dest is smaller than a then src then the string is truncated when | |
68 | dest is full. Add a nul character if there is room in dest. | |
69 | */ | |
70 | ||
51bc4b81 | 71 | extern "C" void StrLib_StrCopy (const char *src_, unsigned int _src_high, char *dest, unsigned int _dest_high); |
7401123f GM |
72 | |
73 | /* | |
74 | IsSubString - returns true if b is a subcomponent of a. | |
75 | */ | |
76 | ||
51bc4b81 | 77 | extern "C" unsigned int StrLib_IsSubString (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high); |
7401123f GM |
78 | |
79 | /* | |
80 | StrRemoveWhitePrefix - copies string, into string, b, excluding any white | |
81 | space infront of a. | |
82 | */ | |
83 | ||
51bc4b81 | 84 | extern "C" void StrLib_StrRemoveWhitePrefix (const char *a_, unsigned int _a_high, char *b, unsigned int _b_high); |
7401123f GM |
85 | |
86 | /* | |
87 | IsWhite - returns TRUE if, ch, is a space or a tab. | |
88 | */ | |
89 | ||
90 | static unsigned int IsWhite (char ch); | |
91 | ||
92 | ||
93 | /* | |
94 | IsWhite - returns TRUE if, ch, is a space or a tab. | |
95 | */ | |
96 | ||
97 | static unsigned int IsWhite (char ch) | |
98 | { | |
99 | return (ch == ' ') || (ch == ASCII_tab); | |
100 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
101 | __builtin_unreachable (); | |
102 | } | |
103 | ||
104 | ||
105 | /* | |
106 | StrConCat - combines a and b into c. | |
107 | */ | |
108 | ||
51bc4b81 | 109 | extern "C" void StrLib_StrConCat (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high, char *c, unsigned int _c_high) |
7401123f GM |
110 | { |
111 | unsigned int Highb; | |
112 | unsigned int Highc; | |
113 | unsigned int i; | |
114 | unsigned int j; | |
115 | char a[_a_high+1]; | |
116 | char b[_b_high+1]; | |
117 | ||
118 | /* make a local copy of each unbounded array. */ | |
119 | memcpy (a, a_, _a_high+1); | |
120 | memcpy (b, b_, _b_high+1); | |
121 | ||
dce2ffd5 | 122 | Highb = StrLib_StrLen ((const char *) b, _b_high); |
7401123f | 123 | Highc = _c_high; |
51bc4b81 | 124 | StrLib_StrCopy ((const char *) a, _a_high, (char *) c, _c_high); |
dce2ffd5 | 125 | i = StrLib_StrLen ((const char *) c, _c_high); |
d08981bf | 126 | j = 0; |
7401123f GM |
127 | while ((j < Highb) && (i <= Highc)) |
128 | { | |
129 | c[i] = b[j]; | |
130 | i += 1; | |
131 | j += 1; | |
132 | } | |
133 | if (i <= Highc) | |
134 | { | |
dce2ffd5 | 135 | c[i] = ASCII_nul; |
7401123f GM |
136 | } |
137 | } | |
138 | ||
139 | ||
140 | /* | |
141 | StrLess - returns TRUE if string, a, alphabetically occurs before | |
142 | string, b. | |
143 | */ | |
144 | ||
51bc4b81 | 145 | extern "C" unsigned int StrLib_StrLess (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high) |
7401123f GM |
146 | { |
147 | unsigned int Higha; | |
148 | unsigned int Highb; | |
149 | unsigned int i; | |
150 | char a[_a_high+1]; | |
151 | char b[_b_high+1]; | |
152 | ||
153 | /* make a local copy of each unbounded array. */ | |
154 | memcpy (a, a_, _a_high+1); | |
155 | memcpy (b, b_, _b_high+1); | |
156 | ||
dce2ffd5 GM |
157 | Higha = StrLib_StrLen ((const char *) a, _a_high); |
158 | Highb = StrLib_StrLen ((const char *) b, _b_high); | |
d08981bf | 159 | i = 0; |
7401123f GM |
160 | while ((i < Higha) && (i < Highb)) |
161 | { | |
162 | if (a[i] < b[i]) | |
163 | { | |
164 | return TRUE; | |
165 | } | |
166 | else if (a[i] > b[i]) | |
167 | { | |
168 | /* avoid dangling else. */ | |
169 | return FALSE; | |
170 | } | |
171 | /* must be equal, move on to next character */ | |
172 | i += 1; | |
173 | } | |
174 | return Higha < Highb; /* substrings are equal so we go on length */ | |
175 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
176 | __builtin_unreachable (); | |
177 | } | |
178 | ||
51bc4b81 | 179 | extern "C" unsigned int StrLib_StrEqual (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high) |
7401123f GM |
180 | { |
181 | unsigned int i; | |
182 | unsigned int higha; | |
183 | unsigned int highb; | |
184 | char a[_a_high+1]; | |
185 | char b[_b_high+1]; | |
186 | ||
187 | /* make a local copy of each unbounded array. */ | |
188 | memcpy (a, a_, _a_high+1); | |
189 | memcpy (b, b_, _b_high+1); | |
190 | ||
191 | higha = _a_high; | |
192 | highb = _b_high; | |
d08981bf | 193 | i = 0; |
7401123f GM |
194 | while ((((i <= higha) && (i <= highb)) && (a[i] != ASCII_nul)) && (b[i] != ASCII_nul)) |
195 | { | |
196 | if (a[i] != b[i]) | |
197 | { | |
198 | return FALSE; | |
199 | } | |
200 | i += 1; | |
201 | } | |
202 | return ! (((i <= higha) && (a[i] != ASCII_nul)) || ((i <= highb) && (b[i] != ASCII_nul))); | |
203 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
204 | __builtin_unreachable (); | |
205 | } | |
206 | ||
51bc4b81 | 207 | extern "C" unsigned int StrLib_StrLen (const char *a_, unsigned int _a_high) |
7401123f GM |
208 | { |
209 | unsigned int High; | |
210 | unsigned int Len; | |
211 | char a[_a_high+1]; | |
212 | ||
213 | /* make a local copy of each unbounded array. */ | |
214 | memcpy (a, a_, _a_high+1); | |
215 | ||
d08981bf | 216 | Len = 0; |
7401123f GM |
217 | High = _a_high; |
218 | while ((Len <= High) && (a[Len] != ASCII_nul)) | |
219 | { | |
220 | Len += 1; | |
221 | } | |
222 | return Len; | |
223 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
224 | __builtin_unreachable (); | |
225 | } | |
226 | ||
c9fba1bc GM |
227 | |
228 | /* | |
229 | StrCopy - copy string src into string dest providing dest is large enough. | |
230 | If dest is smaller than a then src then the string is truncated when | |
231 | dest is full. Add a nul character if there is room in dest. | |
232 | */ | |
233 | ||
51bc4b81 | 234 | extern "C" void StrLib_StrCopy (const char *src_, unsigned int _src_high, char *dest, unsigned int _dest_high) |
7401123f | 235 | { |
c9fba1bc GM |
236 | unsigned int HighSrc; |
237 | unsigned int HighDest; | |
7401123f | 238 | unsigned int n; |
c9fba1bc | 239 | char src[_src_high+1]; |
7401123f GM |
240 | |
241 | /* make a local copy of each unbounded array. */ | |
c9fba1bc | 242 | memcpy (src, src_, _src_high+1); |
7401123f | 243 | |
d08981bf | 244 | n = 0; |
dce2ffd5 | 245 | HighSrc = StrLib_StrLen ((const char *) src, _src_high); |
c9fba1bc GM |
246 | HighDest = _dest_high; |
247 | while ((n < HighSrc) && (n <= HighDest)) | |
7401123f | 248 | { |
c9fba1bc | 249 | dest[n] = src[n]; |
7401123f GM |
250 | n += 1; |
251 | } | |
c9fba1bc | 252 | if (n <= HighDest) |
7401123f | 253 | { |
c9fba1bc | 254 | dest[n] = ASCII_nul; |
7401123f GM |
255 | } |
256 | } | |
257 | ||
258 | ||
259 | /* | |
260 | IsSubString - returns true if b is a subcomponent of a. | |
261 | */ | |
262 | ||
51bc4b81 | 263 | extern "C" unsigned int StrLib_IsSubString (const char *a_, unsigned int _a_high, const char *b_, unsigned int _b_high) |
7401123f GM |
264 | { |
265 | unsigned int i; | |
266 | unsigned int j; | |
267 | unsigned int LengthA; | |
268 | unsigned int LengthB; | |
269 | char a[_a_high+1]; | |
270 | char b[_b_high+1]; | |
271 | ||
272 | /* make a local copy of each unbounded array. */ | |
273 | memcpy (a, a_, _a_high+1); | |
274 | memcpy (b, b_, _b_high+1); | |
275 | ||
dce2ffd5 GM |
276 | LengthA = StrLib_StrLen ((const char *) a, _a_high); |
277 | LengthB = StrLib_StrLen ((const char *) b, _b_high); | |
d08981bf | 278 | i = 0; |
7401123f GM |
279 | if (LengthA > LengthB) |
280 | { | |
281 | while (i <= (LengthA-LengthB)) | |
282 | { | |
d08981bf | 283 | j = 0; |
7401123f GM |
284 | while ((j < LengthB) && (a[i+j] == b[j])) |
285 | { | |
286 | j += 1; | |
287 | } | |
288 | if (j == LengthB) | |
289 | { | |
290 | return TRUE; | |
291 | } | |
292 | else | |
293 | { | |
294 | i += 1; | |
295 | } | |
296 | } | |
297 | } | |
298 | return FALSE; | |
299 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
300 | __builtin_unreachable (); | |
301 | } | |
302 | ||
303 | ||
304 | /* | |
305 | StrRemoveWhitePrefix - copies string, into string, b, excluding any white | |
306 | space infront of a. | |
307 | */ | |
308 | ||
51bc4b81 | 309 | extern "C" void StrLib_StrRemoveWhitePrefix (const char *a_, unsigned int _a_high, char *b, unsigned int _b_high) |
7401123f GM |
310 | { |
311 | unsigned int i; | |
312 | unsigned int j; | |
313 | unsigned int higha; | |
314 | unsigned int highb; | |
315 | char a[_a_high+1]; | |
316 | ||
317 | /* make a local copy of each unbounded array. */ | |
318 | memcpy (a, a_, _a_high+1); | |
319 | ||
d08981bf GM |
320 | i = 0; |
321 | j = 0; | |
dce2ffd5 | 322 | higha = StrLib_StrLen ((const char *) a, _a_high); |
7401123f GM |
323 | highb = _b_high; |
324 | while ((i < higha) && (IsWhite (a[i]))) | |
325 | { | |
326 | i += 1; | |
327 | } | |
328 | while ((i < higha) && (j <= highb)) | |
329 | { | |
330 | b[j] = a[i]; | |
331 | i += 1; | |
332 | j += 1; | |
333 | } | |
334 | if (j <= highb) | |
335 | { | |
336 | b[j] = ASCII_nul; | |
337 | } | |
338 | } | |
339 | ||
206c4f77 | 340 | extern "C" void _M2_StrLib_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) |
7401123f GM |
341 | { |
342 | } | |
343 | ||
206c4f77 | 344 | extern "C" void _M2_StrLib_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) |
7401123f GM |
345 | { |
346 | } |