| /* do not edit automatically generated by mc from Indexing. */ |
| /* Indexing provides a dynamic array of pointers. |
| Copyright (C) 2015-2025 Free Software Foundation, Inc. |
| |
| This file is part of GNU Modula-2. |
| |
| GNU Modula-2 is free software; you can redistribute it and/or modify it under |
| the terms of the GNU General Public License as published by the Free |
| Software Foundation; either version 3, or (at your option) any later |
| version. |
| |
| GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include <stdbool.h> |
| # if !defined (PROC_D) |
| # define PROC_D |
| typedef void (*PROC_t) (void); |
| typedef struct { PROC_t proc; } PROC; |
| # endif |
| |
| # if !defined (TRUE) |
| # define TRUE (1==1) |
| # endif |
| |
| # if !defined (FALSE) |
| # define FALSE (1==0) |
| # endif |
| |
| # include "GStorage.h" |
| # include "Gmcrts.h" |
| #if defined(__cplusplus) |
| # undef NULL |
| # define NULL 0 |
| #endif |
| #define _Indexing_C |
| |
| #include "GIndexing.h" |
| # include "Glibc.h" |
| # include "GStorage.h" |
| # include "GSYSTEM.h" |
| # include "GmcDebug.h" |
| # include "GM2RTS.h" |
| |
| typedef struct Indexing_IndexProcedure_p Indexing_IndexProcedure; |
| |
| # define MinSize 128 |
| typedef struct Indexing__T2_r Indexing__T2; |
| |
| typedef void * *Indexing_PtrToAddress; |
| |
| typedef Indexing__T2 *Indexing_Index__opaque; |
| |
| typedef unsigned char *Indexing_PtrToByte; |
| |
| struct Indexing__T2_r { |
| void * ArrayStart; |
| unsigned int ArraySize; |
| unsigned int Used; |
| unsigned int Low; |
| unsigned int High; |
| bool Debug; |
| unsigned int Map; |
| }; |
| |
| |
| /* |
| InitIndex - creates and returns an Index. |
| */ |
| |
| extern "C" Indexing_Index Indexing_InitIndex (unsigned int low); |
| |
| /* |
| KillIndex - returns Index to free storage. |
| */ |
| |
| extern "C" Indexing_Index Indexing_KillIndex (Indexing_Index i); |
| |
| /* |
| DebugIndex - turns on debugging within an index. |
| */ |
| |
| extern "C" Indexing_Index Indexing_DebugIndex (Indexing_Index i); |
| |
| /* |
| InBounds - returns TRUE if indice, n, is within the bounds |
| of the dynamic array. |
| */ |
| |
| extern "C" bool Indexing_InBounds (Indexing_Index i, unsigned int n); |
| |
| /* |
| HighIndice - returns the last legally accessible indice of this array. |
| */ |
| |
| extern "C" unsigned int Indexing_HighIndice (Indexing_Index i); |
| |
| /* |
| LowIndice - returns the first legally accessible indice of this array. |
| */ |
| |
| extern "C" unsigned int Indexing_LowIndice (Indexing_Index i); |
| |
| /* |
| PutIndice - places, a, into the dynamic array at position i[n] |
| */ |
| |
| extern "C" void Indexing_PutIndice (Indexing_Index i, unsigned int n, void * a); |
| |
| /* |
| GetIndice - retrieves, element i[n] from the dynamic array. |
| */ |
| |
| extern "C" void * Indexing_GetIndice (Indexing_Index i, unsigned int n); |
| |
| /* |
| IsIndiceInIndex - returns TRUE if, a, is in the index, i. |
| */ |
| |
| extern "C" bool Indexing_IsIndiceInIndex (Indexing_Index i, void * a); |
| |
| /* |
| RemoveIndiceFromIndex - removes, a, from Index, i. |
| */ |
| |
| extern "C" void Indexing_RemoveIndiceFromIndex (Indexing_Index i, void * a); |
| |
| /* |
| DeleteIndice - delete i[j] from the array. |
| */ |
| |
| extern "C" void Indexing_DeleteIndice (Indexing_Index i, unsigned int j); |
| |
| /* |
| IncludeIndiceIntoIndex - if the indice is not in the index, then |
| add it at the end. |
| */ |
| |
| extern "C" void Indexing_IncludeIndiceIntoIndex (Indexing_Index i, void * a); |
| |
| /* |
| ForeachIndiceInIndexDo - for each j indice of i, call procedure p(i[j]) |
| */ |
| |
| extern "C" void Indexing_ForeachIndiceInIndexDo (Indexing_Index i, Indexing_IndexProcedure p); |
| |
| |
| /* |
| InitIndex - creates and returns an Index. |
| */ |
| |
| extern "C" Indexing_Index Indexing_InitIndex (unsigned int low) |
| { |
| Indexing_Index__opaque i; |
| |
| Storage_ALLOCATE ((void **) &i, sizeof (Indexing__T2)); |
| i->Low = low; |
| i->High = 0; |
| i->ArraySize = MinSize; |
| Storage_ALLOCATE (&i->ArrayStart, MinSize); |
| i->ArrayStart = libc_memset (i->ArrayStart, 0, static_cast<size_t> (i->ArraySize)); |
| i->Debug = false; |
| i->Used = 0; |
| i->Map = (unsigned int) 0; |
| return static_cast<Indexing_Index> (i); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| KillIndex - returns Index to free storage. |
| */ |
| |
| extern "C" Indexing_Index Indexing_KillIndex (Indexing_Index i) |
| { |
| Storage_DEALLOCATE (&static_cast<Indexing_Index__opaque> (i)->ArrayStart, static_cast<Indexing_Index__opaque> (i)->ArraySize); |
| Storage_DEALLOCATE ((void **) &i, sizeof (Indexing__T2)); |
| return static_cast<Indexing_Index> (NULL); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| DebugIndex - turns on debugging within an index. |
| */ |
| |
| extern "C" Indexing_Index Indexing_DebugIndex (Indexing_Index i) |
| { |
| static_cast<Indexing_Index__opaque> (i)->Debug = true; |
| return i; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| InBounds - returns TRUE if indice, n, is within the bounds |
| of the dynamic array. |
| */ |
| |
| extern "C" bool Indexing_InBounds (Indexing_Index i, unsigned int n) |
| { |
| if (i == NULL) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| else |
| { |
| return (n >= static_cast<Indexing_Index__opaque> (i)->Low) && (n <= static_cast<Indexing_Index__opaque> (i)->High); |
| } |
| ReturnException ("../../gcc/m2/mc/Indexing.def", 20, 1); |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| HighIndice - returns the last legally accessible indice of this array. |
| */ |
| |
| extern "C" unsigned int Indexing_HighIndice (Indexing_Index i) |
| { |
| if (i == NULL) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| else |
| { |
| return static_cast<Indexing_Index__opaque> (i)->High; |
| } |
| ReturnException ("../../gcc/m2/mc/Indexing.def", 20, 1); |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| LowIndice - returns the first legally accessible indice of this array. |
| */ |
| |
| extern "C" unsigned int Indexing_LowIndice (Indexing_Index i) |
| { |
| if (i == NULL) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| else |
| { |
| return static_cast<Indexing_Index__opaque> (i)->Low; |
| } |
| ReturnException ("../../gcc/m2/mc/Indexing.def", 20, 1); |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| PutIndice - places, a, into the dynamic array at position i[n] |
| */ |
| |
| extern "C" void Indexing_PutIndice (Indexing_Index i, unsigned int n, void * a) |
| { |
| typedef unsigned int * *PutIndice__T1; |
| |
| unsigned int oldSize; |
| void * b; |
| PutIndice__T1 p; |
| |
| if (! (Indexing_InBounds (i, n))) |
| { |
| /* avoid gcc warning by using compound statement even if not strictly necessary. */ |
| if (n < static_cast<Indexing_Index__opaque> (i)->Low) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| else |
| { |
| oldSize = static_cast<Indexing_Index__opaque> (i)->ArraySize; |
| while (((n-static_cast<Indexing_Index__opaque> (i)->Low)*sizeof (void *)) >= static_cast<Indexing_Index__opaque> (i)->ArraySize) |
| { |
| static_cast<Indexing_Index__opaque> (i)->ArraySize = static_cast<Indexing_Index__opaque> (i)->ArraySize*2; |
| } |
| if (oldSize != static_cast<Indexing_Index__opaque> (i)->ArraySize) |
| { |
| /* |
| IF Debug |
| THEN |
| printf2('increasing memory hunk from %d to %d |
| ', |
| oldSize, ArraySize) |
| END ; |
| */ |
| Storage_REALLOCATE (&static_cast<Indexing_Index__opaque> (i)->ArrayStart, static_cast<Indexing_Index__opaque> (i)->ArraySize); |
| /* and initialize the remainder of the array to NIL */ |
| b = static_cast<Indexing_Index__opaque> (i)->ArrayStart; |
| b = reinterpret_cast<void *> (reinterpret_cast<char *> (b)+oldSize); |
| b = libc_memset (b, 0, static_cast<size_t> (static_cast<Indexing_Index__opaque> (i)->ArraySize-oldSize)); |
| } |
| static_cast<Indexing_Index__opaque> (i)->High = n; |
| } |
| } |
| b = static_cast<Indexing_Index__opaque> (i)->ArrayStart; |
| b = reinterpret_cast<void *> (reinterpret_cast<char *> (b)+(n-static_cast<Indexing_Index__opaque> (i)->Low)*sizeof (void *)); |
| p = static_cast<PutIndice__T1> (b); |
| (*p) = static_cast<unsigned int *> (a); |
| static_cast<Indexing_Index__opaque> (i)->Used += 1; |
| if (static_cast<Indexing_Index__opaque> (i)->Debug) |
| { |
| if (n < 32) |
| { |
| static_cast<Indexing_Index__opaque> (i)->Map |= (1 << (n )); |
| } |
| } |
| } |
| |
| |
| /* |
| GetIndice - retrieves, element i[n] from the dynamic array. |
| */ |
| |
| extern "C" void * Indexing_GetIndice (Indexing_Index i, unsigned int n) |
| { |
| Indexing_PtrToByte b; |
| Indexing_PtrToAddress p; |
| |
| if (! (Indexing_InBounds (i, n))) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| b = static_cast<Indexing_PtrToByte> (static_cast<Indexing_Index__opaque> (i)->ArrayStart); |
| b += (n-static_cast<Indexing_Index__opaque> (i)->Low)*sizeof (void *); |
| p = (Indexing_PtrToAddress) (b); |
| if (static_cast<Indexing_Index__opaque> (i)->Debug) |
| { |
| if (((n < 32) && (! ((((1 << (n)) & (static_cast<Indexing_Index__opaque> (i)->Map)) != 0)))) && ((*p) != NULL)) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| } |
| return (*p); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| IsIndiceInIndex - returns TRUE if, a, is in the index, i. |
| */ |
| |
| extern "C" bool Indexing_IsIndiceInIndex (Indexing_Index i, void * a) |
| { |
| unsigned int j; |
| Indexing_PtrToByte b; |
| Indexing_PtrToAddress p; |
| |
| j = static_cast<Indexing_Index__opaque> (i)->Low; |
| b = static_cast<Indexing_PtrToByte> (static_cast<Indexing_Index__opaque> (i)->ArrayStart); |
| while (j <= static_cast<Indexing_Index__opaque> (i)->High) |
| { |
| p = (Indexing_PtrToAddress) (b); |
| if ((*p) == a) |
| { |
| return true; |
| } |
| /* we must not INC(p, ..) as p2c gets confused */ |
| b += sizeof (void *); |
| j += 1; |
| } |
| return false; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| RemoveIndiceFromIndex - removes, a, from Index, i. |
| */ |
| |
| extern "C" void Indexing_RemoveIndiceFromIndex (Indexing_Index i, void * a) |
| { |
| unsigned int j; |
| unsigned int k; |
| Indexing_PtrToAddress p; |
| Indexing_PtrToByte b; |
| |
| j = static_cast<Indexing_Index__opaque> (i)->Low; |
| b = static_cast<Indexing_PtrToByte> (static_cast<Indexing_Index__opaque> (i)->ArrayStart); |
| while (j <= static_cast<Indexing_Index__opaque> (i)->High) |
| { |
| p = (Indexing_PtrToAddress) (b); |
| b += sizeof (void *); |
| if ((*p) == a) |
| { |
| Indexing_DeleteIndice (i, j); |
| } |
| j += 1; |
| } |
| } |
| |
| |
| /* |
| DeleteIndice - delete i[j] from the array. |
| */ |
| |
| extern "C" void Indexing_DeleteIndice (Indexing_Index i, unsigned int j) |
| { |
| Indexing_PtrToAddress p; |
| Indexing_PtrToByte b; |
| |
| if (Indexing_InBounds (i, j)) |
| { |
| b = static_cast<Indexing_PtrToByte> (static_cast<Indexing_Index__opaque> (i)->ArrayStart); |
| b += sizeof (void *)*(j-static_cast<Indexing_Index__opaque> (i)->Low); |
| p = (Indexing_PtrToAddress) (b); |
| b += sizeof (void *); |
| p = static_cast<Indexing_PtrToAddress> (libc_memmove (reinterpret_cast <void *> (p), reinterpret_cast <void *> (b), static_cast<size_t> ((static_cast<Indexing_Index__opaque> (i)->High-j)*sizeof (void *)))); |
| static_cast<Indexing_Index__opaque> (i)->High -= 1; |
| static_cast<Indexing_Index__opaque> (i)->Used -= 1; |
| } |
| else |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| } |
| |
| |
| /* |
| IncludeIndiceIntoIndex - if the indice is not in the index, then |
| add it at the end. |
| */ |
| |
| extern "C" void Indexing_IncludeIndiceIntoIndex (Indexing_Index i, void * a) |
| { |
| if (! (Indexing_IsIndiceInIndex (i, a))) |
| { |
| /* avoid gcc warning by using compound statement even if not strictly necessary. */ |
| if (static_cast<Indexing_Index__opaque> (i)->Used == 0) |
| { |
| Indexing_PutIndice (i, Indexing_LowIndice (i), a); |
| } |
| else |
| { |
| Indexing_PutIndice (i, (Indexing_HighIndice (i))+1, a); |
| } |
| } |
| } |
| |
| |
| /* |
| ForeachIndiceInIndexDo - for each j indice of i, call procedure p(i[j]) |
| */ |
| |
| extern "C" void Indexing_ForeachIndiceInIndexDo (Indexing_Index i, Indexing_IndexProcedure p) |
| { |
| unsigned int j; |
| Indexing_IndexProcedure q; |
| |
| j = Indexing_LowIndice (i); |
| q = p; |
| while (j <= (Indexing_HighIndice (i))) |
| { |
| mcDebug_assert (q.proc == p.proc); |
| (*p.proc) (Indexing_GetIndice (i, j)); |
| j += 1; |
| } |
| } |
| |
| extern "C" void _M2_Indexing_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |
| |
| extern "C" void _M2_Indexing_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |