]>
Commit | Line | Data |
---|---|---|
7401123f GM |
1 | /* do not edit automatically generated by mc from Indexing. */ |
2 | /* Indexing provides a dynamic array of pointers. | |
51bc4b81 | 3 | Copyright (C) 2015-2022 Free Software Foundation, Inc. |
7401123f GM |
4 | |
5 | This file is part of GNU Modula-2. | |
6 | ||
7 | GNU Modula-2 is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
9 | Software Foundation; either version 3, or (at your option) any later | |
10 | version. | |
11 | ||
12 | GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License along | |
18 | with gm2; see the file COPYING. If not, write to the Free Software | |
19 | Foundation, 51 Franklin Street, Fifth Floor, | |
20 | Boston, MA 02110-1301, USA. */ | |
21 | ||
22 | #include "config.h" | |
23 | #include "system.h" | |
24 | # if !defined (PROC_D) | |
25 | # define PROC_D | |
26 | typedef void (*PROC_t) (void); | |
27 | typedef struct { PROC_t proc; } PROC; | |
28 | # endif | |
29 | ||
30 | # if !defined (TRUE) | |
31 | # define TRUE (1==1) | |
32 | # endif | |
33 | ||
34 | # if !defined (FALSE) | |
35 | # define FALSE (1==0) | |
36 | # endif | |
37 | ||
38 | # include "GStorage.h" | |
39 | # include "Gmcrts.h" | |
40 | #if defined(__cplusplus) | |
41 | # undef NULL | |
42 | # define NULL 0 | |
43 | #endif | |
44 | #define _Indexing_H | |
45 | #define _Indexing_C | |
46 | ||
47 | # include "Glibc.h" | |
48 | # include "GStorage.h" | |
49 | # include "GSYSTEM.h" | |
50 | # include "GmcDebug.h" | |
51 | # include "GM2RTS.h" | |
52 | ||
53 | typedef struct Indexing_IndexProcedure_p Indexing_IndexProcedure; | |
54 | ||
55 | # define MinSize 128 | |
51bc4b81 | 56 | typedef struct _T2_r _T2; |
7401123f GM |
57 | |
58 | typedef void * *PtrToAddress; | |
59 | ||
51bc4b81 | 60 | typedef _T2 *Indexing_Index; |
7401123f GM |
61 | |
62 | typedef unsigned char *PtrToByte; | |
63 | ||
64 | typedef void (*Indexing_IndexProcedure_t) (void *); | |
65 | struct Indexing_IndexProcedure_p { Indexing_IndexProcedure_t proc; }; | |
66 | ||
51bc4b81 | 67 | struct _T2_r { |
7401123f GM |
68 | void *ArrayStart; |
69 | unsigned int ArraySize; | |
70 | unsigned int Used; | |
71 | unsigned int Low; | |
72 | unsigned int High; | |
73 | unsigned int Debug; | |
74 | unsigned int Map; | |
75 | }; | |
76 | ||
77 | ||
78 | /* | |
79 | InitIndex - creates and returns an Index. | |
80 | */ | |
81 | ||
51bc4b81 | 82 | extern "C" Indexing_Index Indexing_InitIndex (unsigned int low); |
7401123f GM |
83 | |
84 | /* | |
85 | KillIndex - returns Index to free storage. | |
86 | */ | |
87 | ||
51bc4b81 | 88 | extern "C" Indexing_Index Indexing_KillIndex (Indexing_Index i); |
7401123f GM |
89 | |
90 | /* | |
91 | DebugIndex - turns on debugging within an index. | |
92 | */ | |
93 | ||
51bc4b81 | 94 | extern "C" Indexing_Index Indexing_DebugIndex (Indexing_Index i); |
7401123f GM |
95 | |
96 | /* | |
97 | InBounds - returns TRUE if indice, n, is within the bounds | |
98 | of the dynamic array. | |
99 | */ | |
100 | ||
51bc4b81 | 101 | extern "C" unsigned int Indexing_InBounds (Indexing_Index i, unsigned int n); |
7401123f GM |
102 | |
103 | /* | |
104 | HighIndice - returns the last legally accessible indice of this array. | |
105 | */ | |
106 | ||
51bc4b81 | 107 | extern "C" unsigned int Indexing_HighIndice (Indexing_Index i); |
7401123f GM |
108 | |
109 | /* | |
110 | LowIndice - returns the first legally accessible indice of this array. | |
111 | */ | |
112 | ||
51bc4b81 | 113 | extern "C" unsigned int Indexing_LowIndice (Indexing_Index i); |
7401123f GM |
114 | |
115 | /* | |
116 | PutIndice - places, a, into the dynamic array at position i[n] | |
117 | */ | |
118 | ||
51bc4b81 | 119 | extern "C" void Indexing_PutIndice (Indexing_Index i, unsigned int n, void * a); |
7401123f GM |
120 | |
121 | /* | |
122 | GetIndice - retrieves, element i[n] from the dynamic array. | |
123 | */ | |
124 | ||
51bc4b81 | 125 | extern "C" void * Indexing_GetIndice (Indexing_Index i, unsigned int n); |
7401123f GM |
126 | |
127 | /* | |
128 | IsIndiceInIndex - returns TRUE if, a, is in the index, i. | |
129 | */ | |
130 | ||
51bc4b81 | 131 | extern "C" unsigned int Indexing_IsIndiceInIndex (Indexing_Index i, void * a); |
7401123f GM |
132 | |
133 | /* | |
134 | RemoveIndiceFromIndex - removes, a, from Index, i. | |
135 | */ | |
136 | ||
51bc4b81 | 137 | extern "C" void Indexing_RemoveIndiceFromIndex (Indexing_Index i, void * a); |
7401123f GM |
138 | |
139 | /* | |
140 | DeleteIndice - delete i[j] from the array. | |
141 | */ | |
142 | ||
51bc4b81 | 143 | extern "C" void Indexing_DeleteIndice (Indexing_Index i, unsigned int j); |
7401123f GM |
144 | |
145 | /* | |
146 | IncludeIndiceIntoIndex - if the indice is not in the index, then | |
147 | add it at the end. | |
148 | */ | |
149 | ||
51bc4b81 | 150 | extern "C" void Indexing_IncludeIndiceIntoIndex (Indexing_Index i, void * a); |
7401123f GM |
151 | |
152 | /* | |
153 | ForeachIndiceInIndexDo - for each j indice of i, call procedure p(i[j]) | |
154 | */ | |
155 | ||
51bc4b81 | 156 | extern "C" void Indexing_ForeachIndiceInIndexDo (Indexing_Index i, Indexing_IndexProcedure p); |
7401123f GM |
157 | |
158 | ||
159 | /* | |
160 | InitIndex - creates and returns an Index. | |
161 | */ | |
162 | ||
51bc4b81 | 163 | extern "C" Indexing_Index Indexing_InitIndex (unsigned int low) |
7401123f GM |
164 | { |
165 | Indexing_Index i; | |
166 | ||
51bc4b81 | 167 | Storage_ALLOCATE ((void **) &i, sizeof (_T2)); |
7401123f | 168 | i->Low = low; |
d08981bf GM |
169 | i->High = 0; |
170 | i->ArraySize = MinSize; | |
7401123f | 171 | Storage_ALLOCATE (&i->ArrayStart, MinSize); |
dce2ffd5 | 172 | i->ArrayStart = libc_memset (i->ArrayStart, 0, static_cast<size_t> (i->ArraySize)); |
7401123f | 173 | i->Debug = FALSE; |
d08981bf | 174 | i->Used = 0; |
7401123f GM |
175 | i->Map = (unsigned int) 0; |
176 | return i; | |
177 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
178 | __builtin_unreachable (); | |
179 | } | |
180 | ||
181 | ||
182 | /* | |
183 | KillIndex - returns Index to free storage. | |
184 | */ | |
185 | ||
51bc4b81 | 186 | extern "C" Indexing_Index Indexing_KillIndex (Indexing_Index i) |
7401123f GM |
187 | { |
188 | Storage_DEALLOCATE (&i->ArrayStart, i->ArraySize); | |
51bc4b81 | 189 | Storage_DEALLOCATE ((void **) &i, sizeof (_T2)); |
d08981bf | 190 | return NULL; |
7401123f GM |
191 | /* static analysis guarentees a RETURN statement will be used before here. */ |
192 | __builtin_unreachable (); | |
193 | } | |
194 | ||
195 | ||
196 | /* | |
197 | DebugIndex - turns on debugging within an index. | |
198 | */ | |
199 | ||
51bc4b81 | 200 | extern "C" Indexing_Index Indexing_DebugIndex (Indexing_Index i) |
7401123f GM |
201 | { |
202 | i->Debug = TRUE; | |
203 | return i; | |
204 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
205 | __builtin_unreachable (); | |
206 | } | |
207 | ||
208 | ||
209 | /* | |
210 | InBounds - returns TRUE if indice, n, is within the bounds | |
211 | of the dynamic array. | |
212 | */ | |
213 | ||
51bc4b81 | 214 | extern "C" unsigned int Indexing_InBounds (Indexing_Index i, unsigned int n) |
7401123f GM |
215 | { |
216 | if (i == NULL) | |
217 | { | |
218 | M2RTS_HALT (-1); | |
219 | __builtin_unreachable (); | |
220 | } | |
221 | else | |
222 | { | |
223 | return (n >= i->Low) && (n <= i->High); | |
224 | } | |
06c977f8 | 225 | ReturnException ("../../gcc-git-devel-modula2/gcc/m2/mc/Indexing.def", 20, 1); |
7401123f GM |
226 | __builtin_unreachable (); |
227 | } | |
228 | ||
229 | ||
230 | /* | |
231 | HighIndice - returns the last legally accessible indice of this array. | |
232 | */ | |
233 | ||
51bc4b81 | 234 | extern "C" unsigned int Indexing_HighIndice (Indexing_Index i) |
7401123f GM |
235 | { |
236 | if (i == NULL) | |
237 | { | |
238 | M2RTS_HALT (-1); | |
239 | __builtin_unreachable (); | |
240 | } | |
241 | else | |
242 | { | |
243 | return i->High; | |
244 | } | |
06c977f8 | 245 | ReturnException ("../../gcc-git-devel-modula2/gcc/m2/mc/Indexing.def", 20, 1); |
7401123f GM |
246 | __builtin_unreachable (); |
247 | } | |
248 | ||
249 | ||
250 | /* | |
251 | LowIndice - returns the first legally accessible indice of this array. | |
252 | */ | |
253 | ||
51bc4b81 | 254 | extern "C" unsigned int Indexing_LowIndice (Indexing_Index i) |
7401123f GM |
255 | { |
256 | if (i == NULL) | |
257 | { | |
258 | M2RTS_HALT (-1); | |
259 | __builtin_unreachable (); | |
260 | } | |
261 | else | |
262 | { | |
263 | return i->Low; | |
264 | } | |
06c977f8 | 265 | ReturnException ("../../gcc-git-devel-modula2/gcc/m2/mc/Indexing.def", 20, 1); |
7401123f GM |
266 | __builtin_unreachable (); |
267 | } | |
268 | ||
269 | ||
270 | /* | |
271 | PutIndice - places, a, into the dynamic array at position i[n] | |
272 | */ | |
273 | ||
51bc4b81 | 274 | extern "C" void Indexing_PutIndice (Indexing_Index i, unsigned int n, void * a) |
7401123f | 275 | { |
51bc4b81 GM |
276 | typedef unsigned int * *_T1; |
277 | ||
7401123f GM |
278 | unsigned int oldSize; |
279 | void * b; | |
51bc4b81 | 280 | _T1 p; |
7401123f GM |
281 | |
282 | if (! (Indexing_InBounds (i, n))) | |
283 | { | |
284 | /* avoid gcc warning by using compound statement even if not strictly necessary. */ | |
285 | if (n < i->Low) | |
286 | { | |
287 | M2RTS_HALT (-1); | |
288 | __builtin_unreachable (); | |
289 | } | |
290 | else | |
291 | { | |
292 | oldSize = i->ArraySize; | |
293 | while (((n-i->Low)*sizeof (void *)) >= i->ArraySize) | |
294 | { | |
dce2ffd5 | 295 | i->ArraySize = i->ArraySize*2; |
7401123f GM |
296 | } |
297 | if (oldSize != i->ArraySize) | |
298 | { | |
299 | /* | |
300 | IF Debug | |
301 | THEN | |
302 | printf2('increasing memory hunk from %d to %d | |
303 | ', | |
304 | oldSize, ArraySize) | |
305 | END ; | |
306 | */ | |
307 | Storage_REALLOCATE (&i->ArrayStart, i->ArraySize); | |
308 | /* and initialize the remainder of the array to NIL */ | |
309 | b = i->ArrayStart; | |
51bc4b81 | 310 | b = reinterpret_cast<void *> (reinterpret_cast<char *> (b)+oldSize); |
dce2ffd5 | 311 | b = libc_memset (b, 0, static_cast<size_t> (i->ArraySize-oldSize)); |
7401123f GM |
312 | } |
313 | i->High = n; | |
314 | } | |
315 | } | |
316 | b = i->ArrayStart; | |
51bc4b81 GM |
317 | b = reinterpret_cast<void *> (reinterpret_cast<char *> (b)+(n-i->Low)*sizeof (void *)); |
318 | p = static_cast<_T1> (b); | |
319 | (*p) = reinterpret_cast<unsigned int *> (a); | |
7401123f GM |
320 | i->Used += 1; |
321 | if (i->Debug) | |
322 | { | |
323 | if (n < 32) | |
324 | { | |
325 | i->Map |= (1 << (n )); | |
326 | } | |
327 | } | |
328 | } | |
329 | ||
330 | ||
331 | /* | |
332 | GetIndice - retrieves, element i[n] from the dynamic array. | |
333 | */ | |
334 | ||
51bc4b81 | 335 | extern "C" void * Indexing_GetIndice (Indexing_Index i, unsigned int n) |
7401123f GM |
336 | { |
337 | PtrToByte b; | |
338 | PtrToAddress p; | |
339 | ||
340 | if (! (Indexing_InBounds (i, n))) | |
341 | { | |
342 | M2RTS_HALT (-1); | |
343 | __builtin_unreachable (); | |
344 | } | |
51bc4b81 | 345 | b = static_cast<PtrToByte> (i->ArrayStart); |
7401123f GM |
346 | b += (n-i->Low)*sizeof (void *); |
347 | p = (PtrToAddress) (b); | |
348 | if (i->Debug) | |
349 | { | |
350 | if (((n < 32) && (! ((((1 << (n)) & (i->Map)) != 0)))) && ((*p) != NULL)) | |
351 | { | |
352 | M2RTS_HALT (-1); | |
353 | __builtin_unreachable (); | |
354 | } | |
355 | } | |
356 | return (*p); | |
357 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
358 | __builtin_unreachable (); | |
359 | } | |
360 | ||
361 | ||
362 | /* | |
363 | IsIndiceInIndex - returns TRUE if, a, is in the index, i. | |
364 | */ | |
365 | ||
51bc4b81 | 366 | extern "C" unsigned int Indexing_IsIndiceInIndex (Indexing_Index i, void * a) |
7401123f GM |
367 | { |
368 | unsigned int j; | |
369 | PtrToByte b; | |
370 | PtrToAddress p; | |
371 | ||
372 | j = i->Low; | |
51bc4b81 | 373 | b = static_cast<PtrToByte> (i->ArrayStart); |
7401123f GM |
374 | while (j <= i->High) |
375 | { | |
376 | p = (PtrToAddress) (b); | |
377 | if ((*p) == a) | |
378 | { | |
379 | return TRUE; | |
380 | } | |
381 | /* we must not INC(p, ..) as p2c gets confused */ | |
382 | b += sizeof (void *); | |
383 | j += 1; | |
384 | } | |
385 | return FALSE; | |
386 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
387 | __builtin_unreachable (); | |
388 | } | |
389 | ||
390 | ||
391 | /* | |
392 | RemoveIndiceFromIndex - removes, a, from Index, i. | |
393 | */ | |
394 | ||
51bc4b81 | 395 | extern "C" void Indexing_RemoveIndiceFromIndex (Indexing_Index i, void * a) |
7401123f GM |
396 | { |
397 | unsigned int j; | |
398 | unsigned int k; | |
399 | PtrToAddress p; | |
400 | PtrToByte b; | |
401 | ||
402 | j = i->Low; | |
51bc4b81 | 403 | b = static_cast<PtrToByte> (i->ArrayStart); |
7401123f GM |
404 | while (j <= i->High) |
405 | { | |
406 | p = (PtrToAddress) (b); | |
407 | b += sizeof (void *); | |
408 | if ((*p) == a) | |
409 | { | |
410 | Indexing_DeleteIndice (i, j); | |
411 | } | |
412 | j += 1; | |
413 | } | |
414 | } | |
415 | ||
416 | ||
417 | /* | |
418 | DeleteIndice - delete i[j] from the array. | |
419 | */ | |
420 | ||
51bc4b81 | 421 | extern "C" void Indexing_DeleteIndice (Indexing_Index i, unsigned int j) |
7401123f GM |
422 | { |
423 | PtrToAddress p; | |
424 | PtrToByte b; | |
425 | ||
426 | if (Indexing_InBounds (i, j)) | |
427 | { | |
51bc4b81 | 428 | b = static_cast<PtrToByte> (i->ArrayStart); |
7401123f GM |
429 | b += sizeof (void *)*(j-i->Low); |
430 | p = (PtrToAddress) (b); | |
431 | b += sizeof (void *); | |
51bc4b81 | 432 | p = static_cast<PtrToAddress> (libc_memmove (reinterpret_cast<void *> (p), reinterpret_cast<void *> (b), static_cast<size_t> ((i->High-j)*sizeof (void *)))); |
7401123f GM |
433 | i->High -= 1; |
434 | i->Used -= 1; | |
435 | } | |
436 | else | |
437 | { | |
438 | M2RTS_HALT (-1); | |
439 | __builtin_unreachable (); | |
440 | } | |
441 | } | |
442 | ||
443 | ||
444 | /* | |
445 | IncludeIndiceIntoIndex - if the indice is not in the index, then | |
446 | add it at the end. | |
447 | */ | |
448 | ||
51bc4b81 | 449 | extern "C" void Indexing_IncludeIndiceIntoIndex (Indexing_Index i, void * a) |
7401123f GM |
450 | { |
451 | if (! (Indexing_IsIndiceInIndex (i, a))) | |
452 | { | |
453 | /* avoid gcc warning by using compound statement even if not strictly necessary. */ | |
454 | if (i->Used == 0) | |
455 | { | |
456 | Indexing_PutIndice (i, Indexing_LowIndice (i), a); | |
457 | } | |
458 | else | |
459 | { | |
460 | Indexing_PutIndice (i, (Indexing_HighIndice (i))+1, a); | |
461 | } | |
462 | } | |
463 | } | |
464 | ||
465 | ||
466 | /* | |
467 | ForeachIndiceInIndexDo - for each j indice of i, call procedure p(i[j]) | |
468 | */ | |
469 | ||
51bc4b81 | 470 | extern "C" void Indexing_ForeachIndiceInIndexDo (Indexing_Index i, Indexing_IndexProcedure p) |
7401123f GM |
471 | { |
472 | unsigned int j; | |
473 | Indexing_IndexProcedure q; | |
474 | ||
dce2ffd5 | 475 | j = Indexing_LowIndice (i); |
7401123f GM |
476 | q = p; |
477 | while (j <= (Indexing_HighIndice (i))) | |
478 | { | |
479 | mcDebug_assert (q.proc == p.proc); | |
480 | (*p.proc) (Indexing_GetIndice (i, j)); | |
481 | j += 1; | |
482 | } | |
483 | } | |
484 | ||
206c4f77 | 485 | extern "C" void _M2_Indexing_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) |
7401123f GM |
486 | { |
487 | } | |
488 | ||
206c4f77 | 489 | extern "C" void _M2_Indexing_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) |
7401123f GM |
490 | { |
491 | } |